From ca7139c9c959f06cf0db4f852fd74680070ac58f Mon Sep 17 00:00:00 2001 From: Peter Palfrader Date: Mon, 2 Jan 2017 11:42:02 +0100 Subject: do ferm/iptables stuff better --- Generate | 55 +++++++++++++++++++++++++++++++++++++------------------ Push | 13 ++++++++----- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/Generate b/Generate index 6e1b836..632a0db 100755 --- a/Generate +++ b/Generate @@ -1,6 +1,7 @@ #!/usr/bin/ruby require 'yaml' +require 'ipaddr' THISHOST = `hostname`.chomp @@ -408,12 +409,10 @@ hostlist.each{ |host| ip6tables.puts "# Automatically created on #{THISHOST} at #{RIGHTNOW} by #{THISPROGRAM}." ip6tables.puts "PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" ip6tables.puts "echo 'Doing #{$NAMESPACE} VPN rules.'" - if host['ipv6'] - ip6tables.puts "ip6tables --new-chain vpn-#{$NAMESPACE}" - ip6tables.puts "ip6tables --flush vpn-#{$NAMESPACE}" - ip6ferm.puts "# Automatically created on #{THISHOST} at #{RIGHTNOW} by #{THISPROGRAM}." - ip6ferm.puts "def &vpn_#{$NAMESPACE}6() = {" - end + ip6tables.puts "ip6tables --new-chain vpn-#{$NAMESPACE}" + ip6tables.puts "ip6tables --flush vpn-#{$NAMESPACE}" + ip6ferm.puts "# Automatically created on #{THISHOST} at #{RIGHTNOW} by #{THISPROGRAM}." + ip6ferm.puts "def &vpn_#{$NAMESPACE}6() = {" ipferm.puts "# Automatically created on #{THISHOST} at #{RIGHTNOW} by #{THISPROGRAM}." ipferm.puts "def &vpn_#{$NAMESPACE}() = {" @@ -723,11 +722,37 @@ hostlist.each{ |host| ########## # do not filter on remote port as NAT gateways may change ports - iptables.puts "#" - iptables.puts "# to/from #{peer['name']}" - iptables.puts "iptables --append vpn-#{$NAMESPACE} --source #{ peer['host_address'] || '0.0.0.0/0' } --destination #{ host['bind_address'] || host['host_address'] || '0.0.0.0/0' } \\" - iptables.puts " --protocol udp --destination-port #{ host['inet_port'][ peer['name'] ]['local'] } \\" - iptables.puts " --jump ACCEPT" + iptables.puts "#\n# to/from #{peer['name']}" + ip6tables.puts "#\n# to/from #{peer['name']}" + ipferm.puts "#\n# to/from #{peer['name']}" + ip6ferm.puts "#\n# to/from #{peer['name']}" + + src = [] + remote_addr + src << '0.0.0.0/0' << '::/0' if src.size == 0 + src = src.select {|x| IPAddr.new(x) rescue nil } + dst = [] + dst << host['host_address'] if host['host_address'] + dst += host['host_address_extra'] if host['host_address_extra'] + dst << '0.0.0.0/0' << '::/0' if dst.size == 0 + dst = dst.select {|x| IPAddr.new(x) rescue nil } + src.each do |s| + s6 = IPAddr.new(s).ipv6? + dst.each do |d| + d6 = IPAddr.new(d).ipv6? + next if s6 != d6 + + o = d6 ? ip6tables : iptables + i = d6 ? 'ip6tables' : 'iptables' + o.puts "#{i} --append vpn-#{$NAMESPACE} --source #{ s } --destination #{ d } \\" + o.puts " --protocol udp --destination-port #{ host['inet_port'][ peer['name'] ]['local'] } \\" + o.puts " --jump ACCEPT" + + o = d6 ? ip6ferm : ipferm + o.puts " saddr #{ s } daddr #{ d } " + + " proto udp dport #{ host['inet_port'][ peer['name'] ]['local'] } " + + " ACCEPT;" + end + end iptables.puts "iptables --append vpn-#{$NAMESPACE} --source #{ peer['vpn_address'] } --destination #{ host['vpn_address'] } \\" iptables.puts " --protocol tcp --destination-port #{ host['bgp_port'] or '179' } \\" @@ -742,12 +767,6 @@ hostlist.each{ |host| ip6tables.puts " --jump ACCEPT" end - ipferm.puts "#" - ipferm.puts "# to/from #{peer['name']}" - ipferm.puts " saddr #{ peer['host_address'] || '0.0.0.0/0' } daddr #{ host['host_address'] || '0.0.0.0/0' } " + - " proto udp dport #{ host['inet_port'][ peer['name'] ]['local'] } " + - " ACCEPT;" - ipferm.puts " saddr #{ peer['vpn_address'] } daddr #{ host['vpn_address'] } " + " proto tcp dport #{ host['bgp_port'] or '179' } " + " interface #{ peer['ifacename'] } " + @@ -804,7 +823,7 @@ hostlist.each{ |host| ip6tables.close ipferm.puts "}" ipferm.close - ip6ferm.puts "}" if host['ipv6'] + ip6ferm.puts "}" ip6ferm.close bgpd.close diff --git a/Push b/Push index 40303bd..3c4bd7d 100755 --- a/Push +++ b/Push @@ -81,6 +81,7 @@ hosts.each{ |hostname| do_iptables = nil do_ip6tables = nil do_quagga = nil + do_ferm = nil remote.each_pair{|f,h| if ! local.has_key?(f) delete << f @@ -96,6 +97,8 @@ hosts.each{ |hostname| do_iptables = f elsif f =~ /\.ip6tables\.sh$/ do_ip6tables = f + elsif f =~ /\.ferm$/ + do_ferm = f elsif f =~ /\.quagga\.(bgpd|zebra|daemons)$/ do_quagga = true elsif f =~ /\.conf$/ @@ -107,11 +110,12 @@ hosts.each{ |hostname| dir = "#{$NAMESPACE}-#{hostname}/" sys("scp -4 "+copy.collect{|f| dir+f }.join(' ')+" root@#{ssh_hostname}:/etc/openvpn/") if copy.size > 0 commands = [] - commands << "sh ./#{do_iptables} &&\n" if do_iptables - commands << "sh ./#{do_ip6tables} &&\n" if do_ip6tables + commands << "[ -e /etc/ferm/ferm.conf ] || sh ./#{do_iptables} &&\n" if do_iptables + commands << "[ -e /etc/ferm/ferm.conf ] || sh ./#{do_ip6tables} &&\n" if do_ip6tables + commands << "(! [ -e /etc/ferm/ferm.conf ] || ferm /etc/ferm/ferm.conf ) &&\n" if do_ferm #commands << "/etc/init.d/openvpn stop "+stop.join(' ')+" &&\n" if stop.size > 0 #commands << "/etc/init.d/openvpn restart "+restart.join(' ')+" && \n" if restart.size > 0 - commands << "(systemctl daemon-reload || true ) && \n" + commands << "([ -e /bin/systemctl ] && systemctl daemon-reload || true ) && \n" commands << "service openvpn restart && \n" if restart.size > 0 or stop.size > 0 commands << "rm "+delete.join(' ')+" &&\n" if delete.size > 0 command = "cd /etc/openvpn && \n"; @@ -124,7 +128,6 @@ hosts.each{ |hostname| cp -a /etc/openvpn/#{$NAMESPACE}.quagga.daemons /etc/quagga/daemons && chmod 640 /etc/quagga/bgpd.conf /etc/quagga/zebra.conf && chgrp quagga /etc/quagga/bgpd.conf /etc/quagga/zebra.conf && - service quagga restart && - ( ! [ -e /etc/ferm/ferm.conf ] || ferm /etc/ferm/ferm.conf )'") + service quagga restart'") end } -- cgit v1.2.3