Skip to content

Instantly share code, notes, and snippets.

@djmitche
Last active August 29, 2015 14:10
Show Gist options
  • Select an option

  • Save djmitche/de3cda808995b36cde00 to your computer and use it in GitHub Desktop.

Select an option

Save djmitche/de3cda808995b36cde00 to your computer and use it in GitHub Desktop.
firewall-tests and fwunit
fw1_releng_scl3:
type: srx
output: /opt/fwunit/releng/data/fw1_releng_scl3.json
firewall: ...
ssh_username: ...
ssh_password: ...
application-map:
# drop the superfluous 'junos-' prefix, but otherwise leave unchanged:
junos-ssh: ssh
junos-http: http
junos-https: https
junos-ping: ping
junos-bootpc: bootpc
junos-bootps: bootps
junos-dhcp-client: dhcp-client
junos-dhcp-relay: dhcp-relay
junos-dhcp-server: dhcp-server
junos-dns-tcp: dns-tcp
junos-dns-udp: dns-udp
junos-ftp: ftp
junos-ntp: ntp
junos-smtp: smtp
junos-stun: stun
junos-sun-rpc: sun-rpc
junos-sun-rpc-nfs-access: sun-rpc-nfs-access
junos-sun-rpc-udp: sun-rpc-udp
junos-tftp: tftp
fw1_scl3:
type: srx
output: /opt/fwunit/releng/data/fw1_scl3.json
firewall: ...
ssh_username: ...
ssh_password: ...
application-map:
# drop the superfluous 'junos-' prefix, but otherwise leave unchanged:
junos-ssh: ssh
junos-http: http
junos-https: https
junos-ping: ping
junos-bootpc: bootpc
junos-bootps: bootps
junos-dhcp-client: dhcp-client
junos-dhcp-relay: dhcp-relay
junos-dhcp-server: dhcp-server
junos-dns-tcp: dns-tcp
junos-dns-udp: dns-udp
junos-ftp: ftp
junos-ntp: ntp
junos-smtp: smtp
junos-stun: stun
junos-sun-rpc: sun-rpc
junos-sun-rpc-nfs-access: sun-rpc-nfs-access
junos-sun-rpc-udp: sun-rpc-udp
junos-tftp: tftp
# just to add this to "any"
tcp-82: tcp-82
aws_releng:
type: aws
output: /opt/fwunit/releng/data/aws_releng.json
dynamic_subnets: [build, test, try, build.servo, bb]
regions: [us-east-1, us-west-1, us-west-2]
credentials:
...
application-map:
22/tcp: ssh
80/tcp: http
443/tcp: https
445/tcp: microsoft-ds-tcp
3306/tcp: mysql
3389/tcp: rdesktop
5666/tcp: nagios
5900/tcp: vnc
8000-8999/tcp: buildbot-http
9000-9999/tcp: buildbot-rpc
8080/tcp: httpproxy
8140/tcp: puppet
5672/tcp: amqp
9100-9120/tcp: buildbot-sign
"*/icmp": ping # not quite accurate, but close..
releng:
type: combine
require: [aws_releng, fw1_scl3, fw1_releng_scl3]
output: /opt/fwunit/releng/data/releng.json
address_spaces:
fw1_scl3: [10.22.0.0/16]
fw1_releng_scl3: [10.26.0.0/16]
aws_releng: [10.130.0.0/16, 10.132.0.0/16, 10.134.0.0/16]

Objective

We want to describe our flow configuration is: what's allowed, what's not. We want that description in a format that can be read by people who aren't network engineers, including prose commentary and links to bugs. And we want to be able to verify that the description programmatically, so that we know it's accurate.

Solution Summary

Programmatic tests!

Python test code, complete with docstrings, comments, and a few utilities to link test cases to bugs.

This allows us to be as specific as we need to be, while not defining every possible flow. We can leave things unspecified when they don't matter.

Details

I developed fwunit to gather information about flows as implemented (pulling directly from the SRXes and from AWS). Then I wrote a collection of test files, stored in a private firewall-tests repository.

On fwunit1.private.releng.scl3.mozilla.com, there's a nightly fwunit run followed by a run of the tests. I get emailed on test failure. There's also an easy way to run tests against the last night's data, for updating the test scripts.

See test_deploystudio.py for an example of the test script. The fwunit config is in fwunit.yaml , which describes how configuration is pulled from the firewalls and AWS, and how "apps" are determined.

Benefits Reaped

Already, this has been a big win.

Remaining Work

  • Find a process to involve more groups than just me in this process
  • Write tests for more bits of the network:
    • pulse
    • slaveapi
    • vcs sync
    • winadmin
    • relengweb
    • partner-repack
    • celery
    • mozpool
    • blobuploader
    • dev-stage, dev-master, etc.
    • cruncher
    • nagios
  • Add features to suit opsec's needs

This is actually a little vague -- updating tests is a lot to ask of either netops or releng, and the value is difficult to quantify. When the tests fail, it can be very difficult to figure out why and how to fix them, even with a deep background in firewall configs, AWS security groups, and our IPv4 architecture. As an engineer, it's tempting to treat this as a test suite, rather than as a document, but that's not its primary value. So how do we meet the objective with minimal requirements on other teams?

from networks import *
from fwunit.tests import Rules
rules = Rules('releng')
# hosts
install_build = IPSet([host('install.build.releng.scl3.mozilla.com')])
install_test = IPSet([host('install.test.releng.scl3.mozilla.com')])
# tests
"""
We have two DeployStudio servers -- one in the build VLAN and one in the test
VLAN -- due to the inability of a single DeployStudio installation to support
the range of operating system versions and hardware that we have. The server
in the test VLAN is only used within that VLAN, while the server in the build
VLAN supports reimaging on several other VLANs.
Note that we ran into some crazy bugs trying to support the srv VLAN from
install.build in bug 1075887. The rules to support such reimaging are still in
place, but the errors are not fixed and reimaging doesn't actually work.
The 'deploystudio' app is described in bug 1056894, and includes:
application-set deploystudio {
application deploystudio-https;
application afpovertcp;
application junos-tftp;
application junos-sun-rpc-tcp;
application junos-sun-rpc-udp;
application junos-sun-rpc-portmap-tcp;
application junos-sun-rpc-portmap-udp;
application junos-sun-rpc-nfs-tcp;
application junos-sun-rpc-nfs-udp;
application junos-sun-rpc-mountd-tcp;
application junos-sun-rpc-mountd-udp;
}
As uncovered in bug 1075887, Netboot also requires a flow *from* the
DeployStudio server, *to* the client. We encapsulate that in the
'deploystudio-reverse' app:
application deploystudio-reverse {
protocol udp;
destination-port 68;
}
"""
def test_install_build():
"""relabs, try, srv, and build all have access to
install.build.releng.scl3 via deploystudio, and the reverse flows are
allowed via deploystudio-reverse."""
for vlan in [relabs_releng_scl3, try_releng_scl3, srv_releng_scl3, build_releng_scl3]:
rules.assertPermits(vlan, install_build, 'deploystudio')
rules.assertPermits(install_build, vlan, 'deploystudio-reverse')
def test_install_test():
"""test.releng.scl3 has access to install.test.releng.scl3 via the
'deploystudio' app, and the reverse via deploystudio-reverse."""
for vlan in [test_releng_scl3]:
rules.assertPermits(vlan, install_test, 'deploystudio')
rules.assertPermits(install_test, vlan, 'deploystudio-reverse')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment