Skip to content
This repository has been archived by the owner on Jan 2, 2024. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gesquive committed Oct 26, 2017
0 parents commit f4b87da
Show file tree
Hide file tree
Showing 20 changed files with 1,271 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=4

[{.babelrc,.stylelintrc,jest.config,.eslintrc,*.json,*.jsb3,*.jsb2,*.bowerrc,*.yml,*.yaml}]
indent_style=space
indent_size=2

[*.go]
indent_style=tab
tab_width=4

[Makefile]
indent_style=tab
tab_width=4
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_output/
testData/

*.cfg
*.yml

shield
Vagrantfile
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2017 Gus Esquivel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
139 changes: 139 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#
# Makefile
#
# The kickoff point for all project management commands.
#

GOCC := go

# Program version
VERSION := $(shell git describe --always --tags)

# Binary name for bintray
BIN_NAME=shield

# Project owner for bintray
OWNER=gesquive

# Project name for bintray
PROJECT_NAME=shield

# Project url used for builds
# examples: github.com, bitbucket.org
REPO_HOST_URL=github.com

# Grab the current commit
GIT_COMMIT=$(shell git rev-parse HEAD)

# Check if there are uncommited changes
GIT_DIRTY=$(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true)

# Use a local vendor directory for any dependencies; comment this out to
# use the global GOPATH instead
# GOPATH=$(PWD)

INSTALL_PATH=$(GOPATH)/src/${REPO_HOST_URL}/${OWNER}/${PROJECT_NAME}
LOCAL_BIN=bin
GOTEMP:=$(shell mktemp -d)

export PATH := ${LOCAL_BIN}:${PATH}

default: test build

.PHONY: help
help:
@echo 'Management commands for $(PROJECT_NAME):'
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}'

.PHONY: build
build: ## Compile the project
@echo "building ${OWNER} ${BIN_NAME} ${VERSION}"
@echo "GOPATH=${GOPATH}"
${GOCC} build -ldflags "-X main.version=${VERSION} -X main.dirty=${GIT_DIRTY}" -o ${BIN_NAME}

.PHONY: install
install: build ## Install the binary
install -d ${DESTDIR}/usr/local/bin/
install -m 755 ./${BIN_NAME} ${DESTDIR}/usr/local/bin/${BIN_NAME}

.PHONY: deps
deps: glide ## Download project dependencies
glide install

.PHONY: test
test: ## Run golang tests
${GOCC} test ./...

.PHONY: bench
bench: ## Run golang benchmarks
${GOCC} test -benchmem -bench=. ./...

.PHONY: clean
clean: ## Clean the directory tree
${GOCC} clean
rm -f ./${BIN_NAME}.test
rm -f ./${BIN_NAME}
rm -rf ./${LOCAL_BIN}
rm -rf ./dist

.PHONY: build-dist
build-dist: gox
gox -verbose \
-ldflags "-X main.version=${VERSION} -X main.dirty=${GIT_DIRTY}" \
-os="linux darwin windows" \
-arch="amd64 386" \
-output="dist/{{.OS}}-{{.Arch}}/{{.Dir}}" .

.PHONY: package-dist
package-dist: gop
gop --delete \
--os="linux" \
--arch="amd64 386" \
--archive="tar.gz" \
--files="LICENSE README.md pkg" \
--input="dist/{{.OS}}-{{.Arch}}/{{.Dir}}" \
--output="dist/{{.Dir}}-${VERSION}-{{.OS}}-{{.Arch}}.{{.Archive}}" .

.PHONY: dist
dist: build-dist package-dist ## Cross compile and package the full distribution

.PHONY: fmt
fmt: ## Reformat the source tree with gofmt
find . -name '*.go' -not -path './.vendor/*' -exec gofmt -w=true {} ';'

.PHONY: link
link: $(INSTALL_PATH) ## Symlink this project into the GOPATH
$(INSTALL_PATH):
@mkdir -p `dirname $(INSTALL_PATH)`
@ln -s $(PWD) $(INSTALL_PATH) >/dev/null 2>&1

${LOCAL_BIN}:
@mkdir -p ${LOCAL_BIN}

.PHONY: glide
glide: bin/glide
bin/glide: ${LOCAL_BIN}
@echo "Installing glide"
@export GOPATH=${GOTEMP} && ${GOCC} get -u github.com/Masterminds/glide
@cp ${GOTEMP}/bin/glide ${LOCAL_BIN}
@glide --version
@rm -rf ${GOTEMP}

.PHONY: gox
gox: bin/gox
bin/gox: ${LOCAL_BIN}
@echo "Installing gox"
@GOPATH=${GOTEMP} ${GOCC} get -u github.com/mitchellh/gox
@cp ${GOTEMP}/bin/gox ${LOCAL_BIN}/gox
@rm -rf ${GOTEMP}

.PHONY: gop
gop: bin/gop
bin/gop: ${LOCAL_BIN}
@echo "Installing gop"
@export GOPATH=${GOTEMP} && ${GOCC} get -u github.com/gesquive/gop
@cp ${GOTEMP}/bin/gop ${LOCAL_BIN}
@gop --version
@rm -rf ${GOTEMP}

92 changes: 92 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# shield
[![Travis CI](https://img.shields.io/travis/gesquive/shield/master.svg?style=flat-square)](https://travis-ci.org/gesquive/shield)
[![Software License](https://img.shields.io/badge/License-MIT-orange.svg?style=flat-square)](https://github.com/gesquive/shield/blob/master/LICENSE)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/gesquive/shield)

An iptables firewall manager.

This program was created to help account for some of the shortcomings of iptable rules. It allows you to define rules based on url's instead of just IP addresses.

## Installing

### Compile
This project has been tested with go1.9+ on Ubuntu 16.04. Just run `go get -u github.com/gesquive/shield` and the executable should be built for you automatically in your `$GOPATH`.

Optionally you can clone the repo and run `make install` to build and copy the executable to `/usr/local/bin/` with correct permissions.

### Download
Alternately, you can download the latest release for your platform from [github](https://github.com/gesquive/shield/releases/latest).

Once you have an executable, make sure to copy it somewhere on your path like `/usr/local/bin`.
If on a \*nix system, make sure to run `chmod +x /path/to/shield`.

## Configuration

### Precedence Order
The application looks for variables in the following order:
- command line flag
- environment variable
- config file variable
- default

So any variable specified on the command line would override values set in the environment or config file.

### Config File
The application looks for a configuration file at the following locations in order:
- `config.yml`
- `~/.config/shield/config.yml`
- `/etc/shield/config.yml`

If you are planning to run this app as a cron job, it is recommended that you place the config in `/etc/shield/config.yml`.

### Environment Variables
Optionally, instead of using a config file you can specify config entries as environment variables. Use the prefix "SHIELD_" in front of the uppercased variable name. For example, the config variable `ipv4-only` would be the environment variable `SHIELD_IPV4_ONLY`.

### Cron Job
This application was developed to run from a scheduler such as cron.

You can use any scheduler that can run the `shield` with sufficient privledges. An example cron script can be found in the `pkg/services` directory. A logrotate script can also be found in the `pkg/services` directory. All of the configs assume the user to run as is named `shield`, make sure to change this if needed.

## Usage

```console
Manage and update your iptables firewall rules

Usage:
shield [command]

Available Commands:
help Help about any command
reload Reload the firewall rules
save Output the generated firewall rules
status Report the firewall status
unload Clear the firewall, accept all traffic
up Bring up the firewall(s)

Flags:
-c, --config string config file (default is $HOME/.config/shield.yml)
-h, --help help for shield
-4, --ipv4-only Apply command to IPv4 rules only.
-6, --ipv6-only Apply command to IPv6 rules only.
-l, --log-file string Path to log file
-r, --rules string The templated firewall rules
-V, --version Show the version and exit
```

Optionally, a hidden debug flag is available in case you need additional output.
```console
Hidden Flags:
-D, --debug Include debug statements in log output
```

## Documentation

This documentation can be found at github.com/gesquive/shield

## License

This package is made available under an MIT-style license. See LICENSE.

## Contributing

PRs are always welcome!
30 changes: 30 additions & 0 deletions cmd/load.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cmd

import (
"github.com/spf13/cobra"
)

// loadCmd represents the load command
var loadCmd = &cobra.Command{
Use: "up",
Aliases: []string{"load", "start"},
Short: "Bring up the firewall(s)",
Long: `Generates the firewall rules and activates them.`,
Run: runLoad,
}

func init() {
RootCmd.AddCommand(loadCmd)

// #viperbug
// loadCmd.Flags().StringP("rules", "r", "",
// "The templated firewall rules")

// viper.BindEnv("rules")

// viper.BindPFlag("rules", loadCmd.Flags().Lookup("rules"))
}

func runLoad(cmd *cobra.Command, args []string) {
loadRules()
}
29 changes: 29 additions & 0 deletions cmd/reload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cmd

import "github.com/spf13/cobra"

// reloadCmd represents the reload command
var reloadCmd = &cobra.Command{
Use: "reload",
Aliases: []string{"restart", "update"},
Short: "Reload the firewall rules",
Long: `Clear, regenerate and load the firewall rules`,
Run: runReload,
}

func init() {
RootCmd.AddCommand(reloadCmd)

// #viperbug
// reloadCmd.Flags().StringP("rules", "r", "",
// "The templated firewall rules")
//
// viper.BindEnv("rules")
//
// viper.BindPFlag("rules", reloadCmd.Flags().Lookup("rules"))
}

func runReload(cmd *cobra.Command, args []string) {
unloadRules()
loadRules()
}
Loading

0 comments on commit f4b87da

Please sign in to comment.