Friday, May 10, 2019

Security Onion Hybrid Hunter 1.0.8 Tech Preview Available for Testing!

We recently announced Security Onion Hybrid Hunter:

We're excited to announce that Hybrid Hunter 1.0.8 is now available for testing!

Major highlights of this release:

  • Suricata 4.1.4
  • Eval and Master installs now ask which components you would like to install
  • Fleet (osquery) now has it's own additional setup script (please see the docs)
  • Fleet setup script now generates auto install packages for Windows, CentOS, and Ubuntu
  • When Fleet setup is completed, all SO nodes will auto install the appropriate auto install package
  • We now have a progress bar during install!
  • The setup script will now tell you if it was successful

Thanks to Josh Brower for his additional work on the osquery integration!



Main Web Page with link to OSquery

Osquery Page with prebuilt binaries

Fleet showing endpoints

osquery dashboard in Kibana

Chef Habitat for Windows: Troubleshooting


Greetings! Today, I'll be reviewing some steps for troubleshooting Habitat on Windows.

Previous Posts:

Chef Habitat on Windows: Basics
Chef Habitat on Windows: Examples


Habitat executable

If you're running hab commands and it's not doing what you expect or you aren't sure what it's actually doing, try enabling debug logging:

$env:RUST_LOG="debug"; $env:RUST_BACKTRACE=1; hab sup run

PowerShell Troubleshooting

So you've written this awesome plan for your app but it throws errors during the build. Now what? How do you troubleshoot those failures since Hab studio cleans up after the build fails? The quickest way is to set breakpoints inside Studio. You can set breakpoints for any cmdlet or function by name to interrupt the build.

Let's take a look at an example where our plan is unpacking our source but it's failing in the install phase.

# Start up the hab studio  hab studio enter  # Let's set the breakpoint  Set-PSBreakpoint -Command Invoke-Install    ID Script Line Command        Variable Action    -- ------ ---- -------        -------- ------     0             Invoke-Install  # Now let's build  build  Entering debug mode. Use h or ? for help.  Hit Command breakpoint on 'Invoke-Install'  At C:\src\plan.ps1:18 char:24  + function Invoke-Install{  +  >  # Now we can troubleshoot.  # I'm going to provide some high level things as there are too many variations to get specific here.  # - Look at your directory structure?  # - Are the right folders there?  # - Are the folders named correctly?  # - Are they named as you expect them?  # - Are the necessary files in the cache folder?  # - Are they named correctly?  # - If you are running commands, try stepping through them manually and review the output.  # - With the breakpoint, you can single step through the commands  by using the `StepInto` option.  # - Type `h` and press enter to get more help for using the debugger.
# If you forget the breakpoint id, we can find it  Get-PSBreakpoint    ID Script Line Command        Variable Action    -- ------ ---- -------        -------- ------     0             Invoke-Install  # Now let's get rid of the breakpoint and run our build all the way through  Remove-PSBreakpoint 0

Logs and folders

Ok, cool. We've got our package running, now how do we see what it's doing?

  • In the studio, it's easy, we run Get-SupervisorLog and BOOM! there's our data. If you aren't in the studio, this cmdlet isn't available.
  • If you launched hab in a cmd or PowerShell window using hab sup run, then your logs will stream in that window.
  • If you are running hab via the Windows Service, then the supervisor logs default to $env:systemdrive\hab\svc\windows-service\logs.
  • If you want to launch the supervisor via another method, you'll need to redirect the output to a file. You'll also need to implement your own log rotation process to keep from filling the drive with logs.

If you are handling your own logging, use the --no-color option when starting the supervisor. This will prevent the text color formatting noise from being saved to your log file.

If you are planning to ingest your logs into another tool, check out the --json-logging option as it may make the log easier to process.

When you're looking at the logs, I'm sure you've noticed the two letters in parentheses, and wondered what they meant. Wonder no more. These letters are called Log Keys and signify the type of log message. Read more about them here.

hab-sup(MR): core/hab-sup (core/hab-sup/0.78.0/20190313123218)  hab-sup(MR): Supervisor Member-ID 9eba6f8580084b0b88f6bddb008e1b13  hab-sup(MR): Starting gossip-listener on  hab-sup(MR): Starting ctl-gateway on  hab-sup(MR): Starting http-gateway on

We reviewed the folder structure in a previous post, however, let's review:

# Fairly obvious, a local cache for storing objects  ├── cache      # Opt in or out of reporting analytics to Chef  │   ├── analytics      # The hart files are cached here when they are downloaded  │   ├── artifacts      # All harts are checksummed and signed. This directory contains the public keys used to validate those signatures  │   ├── keys      # cURL's cacert.pem. Used for fetching the initial hab packages  │   └── ssl  # Contains the cli.toml. This file is created when running hab cli setup  ├── etc  # Info for hab-launch. Things like it's process ID.  ├── launcher  # This is where all packages are extracted.  ├── pkgs      # All of the core Habitat packages required  │   ├── core      # There may be multiple directories here, one for each Hab Origin you use/depend on.  │   └── ...  # Local studios are stored here. This folder shouldn't exist on production machines.  ├── studios  # Contains all of the information about the supervisor rings  ├── sup  # Each supervised service will have a folder under svc\.  └── svc      └── <service-name>          # Output of the templatized config files from the \config\ directory in your hab package          ├── config          # Stored data consumed by app, i.e. databases          ├── data          # Gossiped configuration file that the Supervisor gets from peers in the ring          ├── files          # The lifecycle hooks from the package          ├── hooks          # Logs generated by the service          ├── logs          # Static content          ├── static          # Temp files          └── var


There are a ton of variables available in Hab, so I want to focus on the ones that are the most useful.

  • $HAB_CACHE_SRC_PATH – This is the main cache folder that Hab uses for downloads, extraction, and compilation.
  • $pkg_prefix – The absolute path for your package.
  • $pkg_dirname – This directory is created when Hab extracts an archive. Set to ${pkg_name}-${pkg_version} by default. This is a subfolder of $HAB_CACHE_SRC_PATH

In general, we download and extract to the $HAB_CACHE_SRC_PATH, do any customization needed, then copy to $pkg_prefix. And most of the time, we target $pkg_prefix\bin as this allows us to expose that directory to other Habitat packages via $pkg_bin_dirs=@("bin"). If we specify the $pkg_bin_dirs in our plan, Habitat will automatically add that directory to the PATH of any package that depends on our application.

You may see the variable $pkg_svc_pathand consider copying files there but as a best practice, don't copy binaries or executables there. Instead, configure your service to write data/logs/temp/configs to $pkg_svc_path.

You may notice that there are several instances where there are multiple variables for the same thing, e.g. $pkg_prefix and $PREFIX. In these cases, I tend to use the variables that start with $pkg_ as that's how the majority of the other variables are and I like to keep things as consistent as I can.

Other Notes

Firewall Rules – Depending on how you launch your app, you may need to add an exception to your host based firewall for hab.exe. If you do need one, consider adding it to your init hook of your application.

Promoting/Demoting – So we've got our package built and running in production. Awesome, right? We find a change that we need to make so we go through our process; write code, commit to SCM, pipeline builds and uploads to BLDR, and our node pulls down the new artifact. Easy Peasy. We go check on our app, only to find that something is broken… Now what? Let's roll back. We go into BLDR (or use hab.exe) and we demote our version and we're done, right? Actually no. Habitat will run the newest version available in the cache so it won't see the demotion. To effectively fix our issue, we need to run our process again. Code change, commit, pipeline, etc. Now the supervisor will see a new version available and load it.


As always, I hope you've found some valuable tidbits here. Check back as this post will undoubtedly receive updates as I find new things in Habitat.

If you have any questions or feedback, please feel free to contact me: @jamesmassardo

The post Chef Habitat for Windows: Troubleshooting appeared first on Chef Blog.

Sent from my iPhone

Chef Habitat on Windows: Examples

Greetings! Today, I'll be outlining some examples and patterns for packaging Windows applications with Chef Habitat.

Previous Post:

Chef Habitat on Windows: Basics



These are the main types of patterns we see in the field so I'm going to outline the basic info needed to get started. All applications have their own essence/flavor so they may need additional tuning beyond what's outlined here.

Zipped Artifact


In this example, we have an app that's published as a zipped archive of the application files to URL based storage (Artifactory, S3, etc).

Habitat's default behavior is to download the file, verify the checksum, then unpack the archive into $HAB_CACHE_SRC_PATH/$pkg_name-$pkg_version so we'll only override the Invoke-Install callback.

Source Link


$pkg_name="packer"  $pkg_origin="core"  $pkg_version="1.3.5"  $pkg_maintainer="The Habitat Maintainers <>"  $pkg_license=@('MPL2')  $pkg_bin_dirs=@("bin")  $pkg_source="${pkg_version}/packer_${pkg_version}"  $pkg_shasum="57d30d5d305cf877532e93526c284438daef5db26d984d16ee85e38a7be7cfbb"  function Invoke-Install {    Copy-Item "$HAB_CACHE_SRC_PATH/$pkg_name-$pkg_version/$pkg_name.exe" $pkg_prefix\bin  }

Executable Binary


Next, we'll look at one that's a single executable, in this case NuGet. It's a single executable so there's no need for any unpacking. Since Habitat's default action is to attempt an unpack, we'll need to override the Invoke-Unpack callback to keep it from erroring out.

Source Link


$pkg_name="nuget"    $pkg_origin="core"    $pkg_version="4.6.2"    $pkg_license=('Apache-2.0')    $pkg_upstream_url=""    $pkg_description="NuGet is the package manager for the Microsoft development platform including .NET."    $pkg_maintainer="The Habitat Maintainers <>"    $pkg_source="${pkg_version}/nuget.exe"    $pkg_shasum="2c562c1a18d720d4885546083ec8eaad6773a6b80befb02564088cc1e55b304e"    $pkg_bin_dirs=@("bin")          function Invoke-Unpack { }          function Invoke-Install {      Copy-Item "$HAB_CACHE_SRC_PATH/nuget.exe" "$pkg_prefix/bin" -Force    }

Git Repository


Our app team is diligent about storing their code in a git repo, so let's go straight to the source! Since there's no $pkg_source, Habitat won't try to download or verify, so how do we get our files? We can use the Invoke-Unpack callback to do that for us.

Source Link


$pkg_name="moonsweeper-py"  $pkg_origin="jmassardo"  $pkg_version="0.1.0"  $pkg_maintainer="James Massardo <>"  $pkg_license=@("Apache-2.0")  $pkg_deps=@('jmassardo/python')  $pkg_build_deps=@('core/git')  $pkg_description="Moonsweeper — A minesweeper clone, on a moon with aliens, in PyQt."  $pkg_upstream_url=""  function Invoke-Unpack{      write-output "Attempting to clone repo"      cd $HAB_CACHE_SRC_PATH      git clone  }  function Invoke-Install{      Copy-Item -Path "$HAB_CACHE_SRC_PATH\15-minute-apps\minesweeper" -Destination "$pkg_prefix" -recurse  }

NOTE: Please take note of the two different dependency types: $pkg_deps and $pkg_build_deps.

  • $pkg_deps includes dependencies that are needed during runtime.
  • $pkg_build_deps includes dependencies that are only used during the package build. In our example, we only need core/git to clone the repo during build so there's no need to include those files when we're running in production.

Legacy Folder


There are times when we need to put the source files and the Habitat files together. In this circumstance, we'll reference the $PLAN_CONTEXT variable as it has the location on your local dev machine for the files in your plan directory.

Source Link


$pkg_name="contosouniversity"  $pkg_origin="mwrock"  $pkg_version="0.1.0"  $pkg_maintainer="The Habitat Maintainers <>"  $pkg_license=@("Apache-2.0")  $pkg_deps=@("core/dsc-core")  $pkg_build_deps=@("core/nuget")  $pkg_binds=@{"database"="username password port"}    function Invoke-Build {      Copy-Item $PLAN_CONTEXT/../* $HAB_CACHE_SRC_PATH/$pkg_dirname -recurse -force      nuget restore "$HAB_CACHE_SRC_PATH/$pkg_dirname/C#/$pkg_name/packages.config" -PackagesDirectory "$HAB_CACHE_SRC_PATH/$pkg_dirname/C#/packages" -Source ""      nuget install MSBuild.Microsoft.VisualStudio.Web.targets -Version -OutputDirectory $HAB_CACHE_SRC_PATH/$pkg_dirname/      $env:VSToolsPath = "$HAB_CACHE_SRC_PATH/$pkg_dirname/MSBuild.Microsoft.VisualStudio.Web.targets."      ."$env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" "$HAB_CACHE_SRC_PATH/$pkg_dirname/C#/$pkg_name/${pkg_name}.csproj" /t:Build /p:VisualStudioVersion=14.0      if($LASTEXITCODE -ne 0) {          Write-Error "dotnet build failed!"      }    }        function Invoke-Install {      ."$env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" "$HAB_CACHE_SRC_PATH/$pkg_dirname/C#/$pkg_name/${pkg_name}.csproj" /t:WebPublish /p:WebPublishMethod=FileSystem /p:publishUrl=$pkg_prefix/www    }

MSI Based Installers


Most Windows Admins are familiar with MSI based installers. We really need the files inside the MSI and not the installation instructions so let's use lessmsi to extract the MSI file. Depending on the application, you may need to add some additional actions:

  • Set up additional app requirements such as registry keys via the inithook.
  • Remove these items via the post-stop hook
  • Consider using the reload and/or reconfigure hooks to update registry keys

These actions will allow you to use gossiped data and toml files to update the running config of the app, e.g redirecting a Win32 forms app to a different database server.

Source Link


$pkg_name="rust"  $pkg_origin="core"  $pkg_version="1.33.0"  $pkg_description="Safe, concurrent, practical language"  $pkg_upstream_url=""  $pkg_license=@("Apache-2.0", "MIT")  $pkg_maintainer="The Habitat Maintainers <>"  $pkg_source="$pkg_version-x86_64-pc-windows-msvc.msi"  $pkg_shasum="cc27799843a146745d4054afa5de1f1f5ab19d539d8c522a909b3c8119e46f99"  $pkg_deps=@("core/visual-cpp-redist-2015", "core/visual-cpp-build-tools-2015")  $pkg_build_deps=@("core/lessmsi")  $pkg_bin_dirs=@("bin")  $pkg_lib_dirs=@("lib")  function Invoke-Unpack {    mkdir "$HAB_CACHE_SRC_PATH/$pkg_dirname"    Push-Location "$HAB_CACHE_SRC_PATH/$pkg_dirname"    try {      lessmsi x (Resolve-Path "$HAB_CACHE_SRC_PATH/$pkg_filename").Path    }    finally { Pop-Location }  }  function Invoke-Install {    Copy-Item "$HAB_CACHE_SRC_PATH/$pkg_dirname/rust-$pkg_version-x86_64-pc-windows-msvc/SourceDir/Rust/*" "$pkg_prefix" -Recurse -Force  }  # This isn't always needed  function Invoke-Check() {    (& "$HAB_CACHE_SRC_PATH/$pkg_dirname/Rust/bin/rustc.exe" --version).StartsWith("rustc $pkg_version")  }

EXE Based Installers


A lot of windows utilities come packaged via exe based installers. Here, we'll look at installing 7zip using its exe installer. As you can see, we're starting to develop a pattern, download, unpack, install.

Source Link


$pkg_name="7zip"    $pkg_origin="core"    $pkg_version="16.04"    $pkg_license=@("LGPL-2.1", "unRAR restriction")    $pkg_upstream_url=""    $pkg_description="7-Zip is a file archiver with a high compression ratio"    $pkg_maintainer="The Habitat Maintainers <>"    $pkg_source="$($pkg_version.Replace('.',''))-x64.exe"    $pkg_shasum="9bb4dc4fab2a2a45c15723c259dc2f7313c89a5ac55ab7c3f76bba26edc8bcaa"    $pkg_filename="7z$($pkg_version.Replace('.',''))-x64.exe"    $pkg_bin_dirs=@("bin")          function Invoke-Unpack {      Start-Process "$HAB_CACHE_SRC_PATH/$pkg_filename" -Wait -ArgumentList "/S /D=`"$(Resolve-Path $HAB_CACHE_SRC_PATH)/$pkg_dirname`""    }          function Invoke-Install {      Copy-Item * "$pkg_prefix/bin" -Recurse -Force    }

Windows Role/Feature based installs


Ooo… Here's a tricky one… Let's say we need IIS to support our webapp.

Source Link


$pkg_name="iis-webserverrole"  $pkg_origin="core"  $pkg_version="0.1.0"  $pkg_maintainer="The Habitat Maintainers <>"  $pkg_license=@("Apache-2.0")  $pkg_description="Installs Basic IIS Web Server features"

Hey, wait just a dang minute, where are the callbacks?!? Well… there aren't any. In this case, we can't actually fully package IIS because it's a Windows component. So now what? We still need IIS for our app. We use a different path, the install hook. This hook is triggered when you run hab pkg install …. We'll use it install the features/roles we need. It's not technically packaged in Hab but it is "habatized" in the sense that we can track it as a dependency and trigger the install if it's missing.

# Install hook  function Test-Feature {      Write-Host "Check if IIS-WebServerRole is enabled..."      $(dism /online /get-featureinfo /featurename:IIS-WebServerRole) -contains "State : Enabled"  }  if (!(Test-Feature)) {      Write-Host "Enabling IIS-WebServerRole..."      dism /online /enable-feature /featurename:IIS-WebServerRole      if (!(Test-Feature)) {          Write-Host "IIS-WebServerRole was not enabled!"          exit 1      }  }


I'd like to take credit for writing all these plans but, alas, I can't. Fortunately, the awesome folks on the Habitat team publish these, along with like 600 other core plans, in their github org, Habitat-sh/Core-plans.

If you run across another significant pattern that isn't here, please let me know so I can update this page!

If you have any questions or feedback, please feel free to contact me: @jamesmassardo

The post Chef Habitat on Windows: Examples appeared first on Chef Blog.