diff options
author | Kali Kaneko <kali@leap.se> | 2018-07-06 00:03:45 +0200 |
---|---|---|
committer | Kali Kaneko (leap communications) <kali@leap.se> | 2018-07-07 04:56:57 +0200 |
commit | eb9fd2fda54a17ddcabc596b0b6555ab4e1df205 (patch) | |
tree | ba6e128761c4cfc0dbf3a6fbc7542212bf16fe70 /helper | |
parent | 1cd5eedba79ad555ee486db263b598b195ff2128 (diff) |
[feat] port osx firewall implementation
Diffstat (limited to 'helper')
-rw-r--r-- | helper/darwin.go | 106 |
1 files changed, 103 insertions, 3 deletions
diff --git a/helper/darwin.go b/helper/darwin.go index d1d0ab3..74fe73b 100644 --- a/helper/darwin.go +++ b/helper/darwin.go @@ -14,24 +14,45 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +/* + +This module holds some specific constants for osx, and it also contains the implementation of the pf firewall. + +To inspect the rules in the firewall manually, use the bitmask anchor: + + sudo pfctl -s rules -a com.apple/250.BitmaskFirewall + +*/ + package main import ( + "fmt" "log" "net/http" "os" "os/exec" + "strings" ) const ( - logPath = "/applications/RiseupVPN.app/Contents/helper.log" + logPath = "/Applications/RiseupVPN.app/Contents/helper/helper.log" openvpnPath = "/Applications/RiseupVPN.app/Contents/Resources/openvpn.leap" + + rulefile = "/Applications/RiseupVPN.app/Contents/helper/bitmask.pf.conf" + bitmask_anchor = "com.apple/250.BitmaskFirewall" + gateways_table = "bitmask_gateways" + nameserver = "10.42.0.1" + + pfctl = "/sbin/pfctl" ) func getOpenvpnPath() string { return openvpnPath } +// TODO -- pass extra args to start_openvpn with --up and --down scripts + func kill(cmd *exec.Cmd) error { return cmd.Process.Signal(os.Interrupt) } @@ -39,9 +60,88 @@ func kill(cmd *exec.Cmd) error { type firewallT struct{} func (firewall *firewallT) start(w http.ResponseWriter, r *http.Request) { - log.Println("Start firewall: do nothing, not implemented") + enablePf() + + // TODO pass gateways + //resetGatewaysTable(gateways) + resetGatewaysTable() + + loadBitmaskAnchor() + log.Println("Start firewall: firewall started") } func (firewall *firewallT) stop(w http.ResponseWriter, r *http.Request) { - log.Println("Stop firewall: do nothing, not implemented") + flushBitmaskAnchor() + log.Println("Stop firewall: firewall stopped") +} + +func enablePf() { + cmd := exec.Command(pfctl, "-e") + cmd.Run() +} + +func resetGatewaysTable() { + // TODO pass gateways as parameter instead + gateways := [2]string{"199.58.81.145", "5.79.86.180"} + + log.Println("Resetting gateways") + cmd := exec.Command(pfctl, "-a", bitmask_anchor, "-t", gateways_table, "-T", "delete") + err := cmd.Run() + + for _, gateway := range gateways { + log.Println("Adding Gateway:", gateway) + cmd = exec.Command(pfctl, "-a", bitmask_anchor, "-t", gateways_table, "-T", "add", gateway) + err = cmd.Run() + if err != nil { + log.Printf("Error adding gateway to table: %v", err) + } + } + + cmd = exec.Command(pfctl, "-a", bitmask_anchor, "-t", gateways_table, "-T", "add", nameserver) + err = cmd.Run() + if err != nil { + log.Printf("Error adding nameserver: %v", err) + } + +} + +func getDefaultDevice() string { + out, err := exec.Command("/bin/sh", "-c", "/sbin/route -n get -net default | /usr/bin/grep interface | /usr/bin/awk '{print $2}'").Output() + if err != nil { + log.Printf("Error getting default device") + } + return strings.TrimSpace(bytesToString(out)) +} + +func loadBitmaskAnchor() { + // TODO check that rulefile exists + + dev := getDefaultDevice() + cmdline := fmt.Sprintf("%s -D default_device=%s -a %s -f %s", pfctl, dev, bitmask_anchor, rulefile) + + log.Println("Loading Bitmask Anchor:", cmdline) + + _, err := exec.Command("/bin/sh", "-c", cmdline).Output() + if err != nil { + log.Printf("Error loading Bitmask anchor: %v\n", err) + } +} + +func flushBitmaskAnchor() { + exec.Command(pfctl, "-a", bitmask_anchor, "-F", "all").Run() +} + +func bytesToString(data []byte) string { + return string(data[:]) +} + +// for testing + +/* +func main() { + enablePf() + flushBitmaskAnchor() + resetGatewaysTable() + loadBitmaskAnchor() } +*/ |