38 |
38 |
|
39 |
39 |
Logic:
|
40 |
40 |
Whenever this script is called, one of our nics changed, so flush everything.
|
41 |
|
If nic has a public IP AND a private nic is up, create rules for that private
|
42 |
|
nic.
|
43 |
|
elif nic is private and there is a public nic, create rules for the specific
|
44 |
|
nic
|
45 |
|
else do nothing
|
|
41 |
If the nic is public create the rules for the private net given in the config
|
|
42 |
file
|
|
43 |
Else do nothing
|
46 |
44 |
'''
|
47 |
45 |
|
48 |
46 |
import iptc
|
49 |
47 |
import netifaces
|
50 |
48 |
import sys
|
51 |
49 |
import IPy
|
|
50 |
import ConfigParser
|
|
51 |
import logging
|
|
52 |
import logging.handlers
|
|
53 |
|
|
54 |
CONFIG_FILE = 'file.conf'
|
52 |
55 |
|
53 |
56 |
|
54 |
57 |
def flush(table_name='', chain_name=''):
|
... | ... | |
60 |
63 |
table.flush_entries(chain_name)
|
61 |
64 |
|
62 |
65 |
|
63 |
|
def create_dnat():
|
64 |
|
placeholder
|
65 |
|
|
66 |
|
|
67 |
|
def create_snat(public_ip, private_net, public_iface, private_iface):
|
|
66 |
def create_dnat(cidr, ports, start_port, step, pub_ip):
|
|
67 |
i = 0
|
|
68 |
for ip in IPy.IP(cidr):
|
|
69 |
j = 1
|
|
70 |
for sport in ports:
|
|
71 |
rule = iptc.Rule()
|
|
72 |
rule.dst = pub_ip
|
|
73 |
rule.protocol = "tcp"
|
|
74 |
match = iptc.Match(rule, "tcp")
|
|
75 |
port = int(start_port) + j*int(step) + i
|
|
76 |
match.dport = str(port)
|
|
77 |
rule.add_match(match)
|
|
78 |
target = iptc.Target(rule, "DNAT")
|
|
79 |
rule.target = target
|
|
80 |
rule.target.to_destination = "%s:%s" % (ip, sport)
|
|
81 |
chain = iptc.Chain(iptc.Table(iptc.Table.NAT), "PREROUTING")
|
|
82 |
chain.insert_rule(rule)
|
|
83 |
j = j + 1
|
|
84 |
|
|
85 |
i = i + 1
|
|
86 |
|
|
87 |
|
|
88 |
def create_snat(public_ip, private_net, public_iface):
|
68 |
89 |
chain = iptc.Chain(iptc.Table(iptc.Table.NAT), "POSTROUTING")
|
69 |
90 |
rule = iptc.Rule()
|
|
91 |
private_net = "%s/%s" % (str(IPy.IP(private_net).net()), str(IPy.IP(private_net).netmask()))
|
70 |
92 |
rule.src = private_net
|
71 |
93 |
rule.dst = "!%s" % private_net
|
72 |
94 |
rule.out_interface = public_iface
|
... | ... | |
79 |
101 |
def create_states(private_net, public_iface, private_iface):
|
80 |
102 |
chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "FORWARD")
|
81 |
103 |
rule = iptc.Rule()
|
|
104 |
private_net = "%s/%s" % (str(IPy.IP(private_net).net()), str(IPy.IP(private_net).netmask()))
|
82 |
105 |
rule.src = "!%s" % private_net
|
83 |
106 |
rule.dst = private_net
|
84 |
107 |
rule.out_interface = private_iface
|
... | ... | |
95 |
118 |
'''
|
96 |
119 |
Returns the IP and ip type (PUBLIC/PRIVATE) of interface
|
97 |
120 |
'''
|
|
121 |
nic = dict()
|
98 |
122 |
nic['ip'] = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
|
99 |
123 |
nic['ip_type'] = IPy.IP(nic['ip']).iptype()
|
100 |
124 |
return nic
|
101 |
125 |
|
102 |
126 |
|
103 |
|
def parse_config():
|
104 |
|
placeholder
|
|
127 |
def parse_config(filename):
|
|
128 |
config = ConfigParser.ConfigParser()
|
|
129 |
config.read(filename)
|
|
130 |
return config
|
|
131 |
|
|
132 |
|
|
133 |
def create_remote_logger(host, url, method):
|
|
134 |
logger = logging.getLogger('snf-router')
|
|
135 |
logger.setLevel(logging.INFO)
|
|
136 |
#http_handler = logging.handlers.HTTPHandler(host, url, method)
|
|
137 |
http_handler = logging.handlers.WatchedFileHandler("test.log")
|
|
138 |
formatter = logging.Formatter("%(asctime)s - %(message)s")
|
|
139 |
http_handler.setFormatter(formatter)
|
|
140 |
logger.addHandler(http_handler)
|
|
141 |
return logger
|
105 |
142 |
|
106 |
143 |
|
107 |
144 |
def allow_ssh():
|
108 |
|
placeholder
|
|
145 |
chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "INPUT")
|
|
146 |
rule = iptc.Rule()
|
|
147 |
rule.protocol = "tcp"
|
|
148 |
match = iptc.Match(rule, "tcp")
|
|
149 |
match.dport = "22"
|
|
150 |
rule.add_match(match)
|
|
151 |
target = iptc.Target(rule, "ACCEPT")
|
|
152 |
rule.target = target
|
|
153 |
chain.insert_rule(rule)
|
|
154 |
|
|
155 |
chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "OUTPUT")
|
|
156 |
rule = iptc.Rule()
|
|
157 |
rule.protocol = "tcp"
|
|
158 |
match = iptc.Match(rule, "tcp")
|
|
159 |
match.sport = "22"
|
|
160 |
rule.add_match(match)
|
|
161 |
target = iptc.Target(rule, "ACCEPT")
|
|
162 |
rule.target = target
|
|
163 |
chain.insert_rule(rule)
|
|
164 |
|
|
165 |
def set_policy(table, chain, policy):
|
|
166 |
cur_table = iptc.Table(getattr(iptc.Table, table))
|
|
167 |
cur_chain = iptc.Chain(cur_table, chain)
|
|
168 |
cur_chain.set_policy(policy)
|
109 |
169 |
|
110 |
170 |
|
111 |
|
def deny_all():
|
112 |
|
placeholder
|
|
171 |
def get_public_iface():
|
|
172 |
public_iface = ''
|
|
173 |
for iface in netifaces.interfaces():
|
|
174 |
nic = nic_info(iface)
|
|
175 |
if nic['ip_type'] == 'PUBLIC':
|
|
176 |
public_iface = iface
|
|
177 |
break
|
|
178 |
return public_iface
|
113 |
179 |
|
114 |
180 |
|
115 |
181 |
def main():
|
116 |
|
#log
|
117 |
|
flush("NAT", "PREROUTING")
|
118 |
|
flush("NAT", "POSTROUTING")
|
119 |
|
flush("FILTER", "FORWARD")
|
120 |
|
|
121 |
|
if sys.argv[2] == 'up':
|
122 |
|
#log
|
123 |
|
nic = nic_info(sys.argv[1])
|
124 |
|
if nic['ip_type'] == "PUBLIC":
|
125 |
|
placeholder
|
|
182 |
#read config file
|
|
183 |
config = parse_config(CONFIG_FILE)
|
|
184 |
|
|
185 |
#create logger
|
|
186 |
logger = create_remote_logger(config.get('log', 'host'),
|
|
187 |
config.get('log', 'url'),
|
|
188 |
config.get('log', 'method'))
|
|
189 |
|
|
190 |
nic = nic_info(sys.argv[1])
|
|
191 |
logger.info(nic['ip_type'] + " " + sys.argv[1] + " " + sys.argv[2])
|
|
192 |
|
|
193 |
if sys.argv[2] == 'up' and nic['ip_type'] == "PUBLIC":
|
|
194 |
#flush the old rules
|
|
195 |
flush("NAT", "PREROUTING")
|
|
196 |
flush("NAT", "POSTROUTING")
|
|
197 |
flush("FILTER", "FORWARD")
|
|
198 |
|
|
199 |
#set policy
|
|
200 |
#set_policy("FILTER", "FORWARD", config.get('policy', 'FORWARD'))
|
|
201 |
#set_policy("FILTER", "OUTPUT", config.get('policy', 'OUTPUT'))
|
|
202 |
#set_policy("FILTER", "INPUT", config.get('policy', 'INPUT'))
|
|
203 |
|
|
204 |
# create dnat
|
|
205 |
create_dnat(config.get("private-network", "cidr"),
|
|
206 |
config.get("private-network", "ports").split(","),
|
|
207 |
config.get("private-network", "start_port"),
|
|
208 |
config.get("private-network", "step"),
|
|
209 |
nic["ip"])
|
|
210 |
|
|
211 |
# create snat
|
|
212 |
create_snat(nic['ip'], config.get("private-network","cidr"),
|
|
213 |
sys.argv[1])
|
|
214 |
|
|
215 |
create_states(config.get("private-network","cidr"), sys.argv[1],
|
|
216 |
config.get("private-network","iface"))
|
|
217 |
|
|
218 |
if __name__ == "__main__":
|
|
219 |
main()
|