Skip to content

Commit

Permalink
ssh authentication capture flow
Browse files Browse the repository at this point in the history
  • Loading branch information
mihakralj committed Aug 21, 2023
1 parent 15ea576 commit 19ce72f
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 82 deletions.
42 changes: 26 additions & 16 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ jobs:
run: sudo apt-get install build-essential devscripts debhelper dh-make
shell: bash

- name: Extract version from Makefile
- name: Extract version from root.go
id: extract_version
run: |
VERSION=$(awk -F '=' '/^VERSION/ {print $2}' Makefile)
VERSION=$(grep 'Version[[:space:]]*string' cmd/root.go | awk -F'"' '{ print $2 }')
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "::set-output name=version::${VERSION}"
echo "VERSION=$VERSION"
shell: bash

- name: Build Windows binary
Expand Down Expand Up @@ -79,17 +80,20 @@ jobs:
- name: Check out code
uses: actions/checkout@v3

- name: Extract version from Makefile
- name: Extract version from root.go
id: extract_version
run: echo "VERSION=$(awk -F '=' '/^VERSION/ {print $2}' Makefile)" >> $GITHUB_ENV
run: |
VERSION=$(grep 'Version[[:space:]]*string' cmd/root.go | awk -F'"' '{ print $2 }')
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "::set-output name=version::${VERSION}"
echo "VERSION=$VERSION"
shell: bash

- name: Select XCode
uses: BoundfoxStudios/action-xcode-select@v1
with:
version: 14.2


- name: Import app certificate
run: |
security create-keychain -p ${{ secrets.APPLE_CERTPWD }} build.keychain
Expand Down Expand Up @@ -135,10 +139,6 @@ jobs:
xcrun notarytool submit ./opnsense.pkg --wait --apple-id ${{ secrets.APPLE_NOTARIZATION_USERNAME }} --password ${{ secrets.APPLE_NOTARIZATION_PASSWORD }} --team-id ${{ secrets.APPLE_TEAM_NAME }}
xcrun stapler staple ./opnsense.pkg
- name: Compile .txz package in FreeBSD
id: compile
uses: vmactions/[email protected]
Expand Down Expand Up @@ -184,6 +184,16 @@ jobs:
- name: Check out code
uses: actions/checkout@v3

- name: Set up Git user information
run: |
git config user.name "Miha Kralj"
git config user.email "[email protected]"
- name: Delete existing beta tag
run: |
git tag -d beta || true
git push origin --delete beta || true
- name: Download all artifacts
uses: actions/download-artifact@v2
with:
Expand All @@ -194,20 +204,20 @@ jobs:
ls -l ./bin
shell: bash

- name: Remove Existing Beta Tag
run: |
git tag -d beta || true
git push origin :refs/tags/beta || true
- name: Create Beta Release and Upload Assets
id: create_release
uses: softprops/action-gh-release@v1
with:
prerelease: true
draft: false
tag_name: beta
draft: true
tag_name: ${{ env.VERSION }}
name: opnsense-cli ${{ env.VERSION }}
files: ./bin/opnsense*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ needs.linuxwindows.outputs.version }}

- name: Add beta tag to the new release
run: |
git tag beta ${{ env.VERSION }}
git push origin beta
10 changes: 4 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# run make help for options

# Variables
VERSION=0.4.0
GO=go
BUILD_DIR=build
BINARY_NAME=opnsense
Expand All @@ -28,7 +27,7 @@ help:
clean:
@echo "Cleaning..."
ifeq ($(OS),Windows_NT)
-@rmdir /s /q $(BUILD_DIR)
@if exist $(BUILD_DIR) rmdir /s /q $(BUILD_DIR)
else
-@rm -rf $(BUILD_DIR)
endif
Expand All @@ -44,10 +43,10 @@ build: deps
@echo "Building..."
ifeq ($(OS),Windows_NT)
@if not exist $(BUILD_DIR) mkdir $(BUILD_DIR)
@$(GO) build -ldflags "-X cmd.version=$(VERSION)" -o $(BUILD_DIR)/$(BINARY_NAME).exe .
@$(GO) build -o $(BUILD_DIR)/$(BINARY_NAME).exe .
else
@mkdir -p $(BUILD_DIR)
@$(GO) build -ldflags "-X cmd.version=$(VERSION)" -o $(BUILD_DIR)/$(BINARY_NAME) .
@$(GO) build -o $(BUILD_DIR)/$(BINARY_NAME) .
endif

# Run tests
Expand Down Expand Up @@ -90,5 +89,4 @@ else
@echo "MacOS binary done"
@GOOS=freebsd GOARCH=amd64 $(GO) build -o $(BUILD_DIR)/$(BINARY_NAME)-bsd .
@echo "FreeBSD binary done"
endif

endif
20 changes: 10 additions & 10 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ Administrators typically only two options how to manage the firewall: either th

### Commands

- **`show system <xpath>`**: Retrieves system information from the firewall.
- **`show config <xpath>`**: Displays hierarchical segments of `config.xml`.
- **`show backup <config>`**: Lists available backup configs or a specific backup.
- **`show system [<xpath>]`**: Retrieves system information from the firewall.
- **`show config [<xpath>]`**: Displays xpath segment of config.xml.
- **`show backup [<backup.xml>]`**: Lists available backup configs or displays a specific backup.
- **`run <service> <command>`**: Executes commands on OPNsense.
- **`set <xpath> value <value>`**: Sets a value of a specific node in the staging config.
- **`commit`**: Moves staging config to active config.
- **`compare [<config>] [<config>]`**: Compares staging config and active config or any two configs.
- **`discard [<xpath>]`**: Discards a value in the staging config or all changes in the staging config.
- **`save [<config>]`**: Creates a new backup config.
- **`load <config>`**: Moves a specific backup config to active config.
- **`delete <config>`**: Deletes a specific config file.
- **`set <xpath> value <value>`**: Sets a value of a specific node in staging.xml file.
- **`commit`**: Moves staging.xml to active config.xml.
- **`compare [<staging.xml>] [<config.xml>]`**: Compares two config files.
- **`discard [<xpath>]`**: Discards a value (or all changes) in the staging.xml.
- **`save [<backup.xml>]`**: Creates a new backup.xml.
- **`load [<backup.xml>]`**: Restores config.xml from a specific backup.xml. (alias: `restore``)
- **`delete <backup.xml>`**: Deletes a specific backup.xml.

### Flags

Expand Down
31 changes: 21 additions & 10 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

var (
Version string
Version string = "0.5.0"
verbose int
force bool
host string
Expand All @@ -33,6 +33,11 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&force, "force", "f", false, "Accept or bypass checks and prompts")
//rootCmd.PersistentFlags().StringVarP(&configfile, "config", "c", "/conf/config.xml", "path to target config.xml")

rootCmd.Flags().StringVar(&Version, "version", "", "display version of opnsense")
rootCmd.SetHelpCommand(&cobra.Command{
Hidden: true,
})

cobra.OnInitialize(func() {
configfile = "/conf/config.xml"
stagingfile = "/conf/staging.xml"
Expand All @@ -43,22 +48,28 @@ func init() {
}

var rootCmd = &cobra.Command{
Use: "opnsense",
Short: "opnsense is a CLI to manage and monitor OPNsense firewall configuration, check status, change settings, and execute commands.",
Long: `
Description:
opnsense is a command-line utility for managing, configuring, and monitoring OPNsense firewall systems.
It facilitates non-GUI administration, both directly in the shell and remotely via an SSH tunnel.
All interactions with OPNsense utilize the same mechanisms as the Web GUI,
including staged modifications of config.xml and execution of available configd commands.`,
Use: "opnsense [command]",
Short: "CLI to manage and monitor OPNsense firewall systems.",
Long: `Command Line utility to interact with OPNsense firewall.
opnsense CLI is a command-line utility for managing, configuring, and monitoring OPNsense firewall systems.
It facilitates non-GUI administration, both locally on the firewall and remotely via an SSH tunnel.
To avoid entering passwords for each remote call, use 'ssh-add' to add private key to your ssh-agent.`,

Example: ` opnsense -t [email protected] show system - Show system information on remote OPNsense
opnsense show config interfaces/wan --json - Show the inerfaces/wan of config.xml in json format
opnsense show backup -d2 - Show backup details 2 levels deep
opnsense run firmware reboot -f - Reboot OPNsense, force (no confirmation)
opnsense commit - Commit staged changes`,

PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return nil
},
Run: func(cmd *cobra.Command, args []string) {

if len(args) == 0 {
fmt.Println(cmd.Long)
cmd.Help()
os.Exit(0)
}
},
}
Expand Down
21 changes: 14 additions & 7 deletions cmd/action.go → cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ import (
"github.com/spf13/cobra"
)

var actionCmd = &cobra.Command{
Use: "action",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
var runCmd = &cobra.Command{
Use: "run [service] [command] [parameters]",
Short: "Executes commands on OPNsense firewall.",
Long: `Execute registered command on OPNsense.
The 'run' command is used to execute specific command that is registered with 'configctl' on OPNsense.`,

Example: ` opnsense run - List configd services
opnsense run dns - List commands for dns service
opnsense run dhcpd list leases - Show DHCP leases
opnsense run interface flush arp - Flush arp table
opnsense run firmware reboot - Issue a reboot
`,

Cobra is a CLI library for Go that empowers applications.`,
Run: func(cmd *cobra.Command, args []string) {

path := "actions"
Expand Down Expand Up @@ -86,6 +93,6 @@ Cobra is a CLI library for Go that empowers applications.`,
}

func init() {
rootCmd.AddCommand(actionCmd)
rootCmd.AddCommand(runCmd)
// Here you will define your flags and configuration settings.
}
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,4 @@ require (
golang.org/x/mod v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/tools v0.11.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
3 changes: 1 addition & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/tools v0.11.1 h1:ojD5zOW8+7dOGzdnNgersm8aPfcDjhMp12UfG93NIMc=
golang.org/x/tools v0.11.1/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
21 changes: 11 additions & 10 deletions internal/executecmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ package internal

import (
"bytes"
"fmt"
"os/exec"
)

func ExecuteCmd(command, host string) (string, error) {

Log(4,"sh -c %s",command)
Log(4, "sh -c %s", command)
if host == "" {
Log(5, "no target provided; executing command locally.")
out, err := exec.Command("sh", "-c", command).Output()
Expand All @@ -19,21 +17,24 @@ func ExecuteCmd(command, host string) (string, error) {
Log(5, "received results from executed command.")
return string(out), nil
}

sshClient, err := getSSHClient(host)
if err != nil {
return "", err
}

session := sshClient.Session
if err != nil {
return "", fmt.Errorf("failed to create session: %v", err)
if sshClient.Session == nil {
session, err := sshClient.Client.NewSession()
if err != nil {
Log(1, "%s", err)
return "", err
}
sshClient.Session = session
}
defer session.Close()

var stdoutBuf bytes.Buffer
session.Stdout = &stdoutBuf

err = session.Run(command)
sshClient.Session.Stdout = &stdoutBuf
err = sshClient.Session.Run(command)
if err != nil {
Log(3, "failed to execute sh command. %s", err.Error())
return "", err
Expand Down
Loading

0 comments on commit 19ce72f

Please sign in to comment.