Compare commits
	
		
			17 Commits
		
	
	
		
			2022.1
			...
			f39d319b25
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f39d319b25 | |||
| 3e64189f8f | |||
| 45dc173ea7 | |||
| 9b85bfabdb | |||
| 969ba0f64c | |||
| d9b5d36835 | |||
| 9f86e143fe | |||
| a49da1f3ef | |||
| 36ff86c71e | |||
| 29f6e6093b | |||
| ccc7165d1b | |||
| 72f0e095ca | |||
| 61869049a0 | |||
| c868c63aa7 | |||
| 9875dccec0 | |||
| 359514e581 | |||
| 9ed6b65b6d | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -12,3 +12,6 @@ htmlcov/ | ||||
| dist/ | ||||
| build/ | ||||
| *.egg-info/ | ||||
|  | ||||
| coverage.xml | ||||
| report.xml | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| run tests: | ||||
|   stage: test | ||||
|   image: python:3.8 | ||||
|   image: python:3.9 | ||||
|   script: | ||||
|     - pip install pytest pytest-cov pytest-mock pytest-flask | ||||
|     - pip install Flask-HTTPAuth | ||||
| @ -11,7 +11,9 @@ run tests: | ||||
|   artifacts: | ||||
|     when: always | ||||
|     reports: | ||||
|       cobertura: coverage.xml | ||||
|       coverage_report: | ||||
|         coverage_format: cobertura | ||||
|         path: coverage.xml | ||||
|       junit: report.xml | ||||
|   tags: | ||||
|     - docker | ||||
|  | ||||
							
								
								
									
										3
									
								
								CHANGELOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								CHANGELOG
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| - 2023.1 | ||||
|  | ||||
| * Implement #3, a /ping health check endpoint | ||||
							
								
								
									
										127
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								README.md
									
									
									
									
									
								
							| @ -1,3 +1,130 @@ | ||||
| [](https://gitlab.niet.verweg.com/ruben/jail2ban-pf/-/commits/main) | ||||
| [](https://gitlab.niet.verweg.com/ruben/jail2ban-pf/-/commits/main) | ||||
|  | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
|  | ||||
| * Install uwsgi  | ||||
|  | ||||
| ``` | ||||
| sudo pkg install www/uwsgi | ||||
| ``` | ||||
|  | ||||
| * Clone this repository | ||||
|  | ||||
| ## Configuration | ||||
|  | ||||
| ### rc.conf | ||||
|  | ||||
| * Use the following for configuring uwsgi in rc.conf | ||||
|  | ||||
| ``` | ||||
| sudo sysrc uwsgi\_enable="YES" | ||||
| sudo sysrc uwsgi\_profiles="jail2ban\_pf" | ||||
| sudo sysrc uwsgi\_jail2ban\_pf\_flags="-L -M --uid \_jail2ban --python-path /opt/jail2ban-pf --wsgi-file /opt/jail2ban-pf/wsgi.py --stats 127.0.0.1:9191 --socket 127.0.0.1:3031 --chdir /var/empty --callable app --manage-script-name" | ||||
| ``` | ||||
|  | ||||
| ### jail2ban | ||||
|  | ||||
| * Configure <installation root>/instance/config.py | ||||
|  | ||||
| ``` | ||||
| SECRET\_KEY = os.urandom(32).hex() | ||||
| AUTHFILE = '/usr/local/etc/jail2ban-pf-users.txt' | ||||
| ``` | ||||
|  | ||||
| ### nginx | ||||
|  | ||||
| * Configure a nginx upstream and vhost | ||||
|  | ||||
| _Of course you can listen on ipv4/ipv6 but you want to protect these addresses from inadvertent or malicious probes_ | ||||
|  | ||||
|     upstream uwsgi_pf_jail2ban { | ||||
|         server 127.0.0.1:3031; | ||||
|     } | ||||
|  | ||||
|     server { | ||||
|         listen       unix:/path/to/jail_1/var/run/pf2ban/pf_jail2ban.sock; | ||||
|         listen       unix:/path/to/jail_2/var/run/pf2ban/pf_jail2ban.sock; | ||||
|         listen       unix:/path/to/jail_3/var/run/pf2ban/pf_jail2ban.sock; | ||||
|         server_name  _; | ||||
|  | ||||
|         location / { | ||||
|             index     index.html index.htm index.php; | ||||
|             allow all; | ||||
|             include /usr/local/etc/nginx/uwsgi_params-dist; | ||||
|             uwsgi_pass uwsgi_pf_jail2ban; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| ### /etc/pf.conf | ||||
|  | ||||
| * Place anchors in pf for jail2ban to use. You probably want to place the early in your existing pf configuration | ||||
|  | ||||
| ``` | ||||
| anchor "f2b/*" | ||||
| anchor f2b-jail { | ||||
|     anchor "jail1_fqdn" to { <addr_jail1>, <addr_extra_jail1>, <addr_extra6_jail1> } | ||||
|     anchor "jail2_fqdn" to { <addr_jail2>, <addr_extra_jail2>, <addr_extra6_jail2> } | ||||
|     anchor "jail3_fqdn" to { <addr_jail3>, <addr_extra_jail3>, <addr_extra6_jail3> } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Having seperate anchors per jail makes it possible to have fine grained | ||||
| blocking: Something that is harmful to jail2 might be perfectly legit for jail2. | ||||
|  | ||||
| #### Checking rules/tables made with fail2ban/jail2ban | ||||
| Fail2ban will (re)create the per anchor rules on startup, and populate the designated address tables with offenders, e.g.: | ||||
|  | ||||
|     sudo pfctl -a f2b-jail/jail1\_fqdn -T show -t f2b-recidive | ||||
|     192.0.2.66 | ||||
|     2001:db8:abad:cafe:0bad:f00d | ||||
|  | ||||
| And the rules referencing these tables | ||||
|  | ||||
|     sudo pfctl -a 'f2b-jail/jail1\_fqdn' -s rules | ||||
|     block drop quick proto tcp from <f2b-dovecot> to any port = pop3 | ||||
|     block drop quick proto tcp from <f2b-dovecot> to any port = pop3s | ||||
|     block drop quick proto tcp from <f2b-dovecot> to any port = imap | ||||
|     block drop quick proto tcp from <f2b-dovecot> to any port = imaps | ||||
|     block drop quick proto tcp from <f2b-dovecot> to any port = submission | ||||
|     block drop quick proto tcp from <f2b-dovecot> to any port = smtps | ||||
|     block drop quick proto tcp from <f2b-dovecot> to any port = sieve | ||||
|     block drop quick proto tcp from <f2b-sendmail-auth> to any port = submission | ||||
|     block drop quick proto tcp from <f2b-sendmail-auth> to any port = smtps | ||||
|     block drop quick proto tcp from <f2b-sendmail-auth> to any port = smtp | ||||
|     block drop quick proto tcp from <f2b-sshd> to any port = ssh | ||||
|     block drop quick proto tcp from <f2b-recidive> to any | ||||
|      | ||||
| ### fail2ban | ||||
|  | ||||
| * Create the following action plugin for fail2ban on the jail desiring to use fail2ban/jail2ban | ||||
|  | ||||
| ``` | ||||
| cat <<'EOT' | tee /usr/local/etc/fail2ban/action.d/jail2ban-pf.conf > /dev/null | ||||
| Definition] | ||||
| actionstart = curl --unix-socket <jail2ban_sock> --basic -u '<jail2ban_user>:<jail2ban_pass>' -XPUT -H 'Content-Type: application/json' -d '{"port":"<actiontype>","name":"<name>","protocol":"<protocol>"}' http://localhost/register | ||||
| actionstart_on_demand = false | ||||
| actionstop = curl --unix-socket <jail2ban_sock> --basic -u '<jail2ban_user>:<jail2ban_pass>' -XDELETE -H 'Content-Type: application/json' -d '{"port":"<actiontype>","name":"<name>","protocol":"<protocol>"}' http://localhost/register | ||||
| actionflush = curl --unix-socket <jail2ban_sock> --basic -u '<jail2ban_user>:<jail2ban_pass>' -X GET http://localhost/flush/<name> | ||||
| actioncheck =  | ||||
| actionban = curl --unix-socket <jail2ban_sock> --basic -u '<jail2ban_user>:<jail2ban_pass>' -X PUT -H 'Content-Type: application/json' -d '{"name":"<name>","ip":"<ip>"}' http://localhost/ban | ||||
| actionunban = curl --unix-socket <jail2ban_sock> --basic -u '<jail2ban_user>:<jail2ban_pass>' -X DELETE -H 'Content-Type: application/json' -d '{"name":"<name>","ip":"<ip>"}' http://localhost/ban | ||||
| [Init] | ||||
| protocol = tcp | ||||
| actiontype = <multiport> | ||||
| allports = any | ||||
| multiport = any port {<port>} | ||||
| jail2ban_sock = /var/run/pf2ban/jail2ban.sock | ||||
| jail2ban_user = login as set in password file for jail2ban | ||||
| jail2ban_pass = password as set in password file for jail2ban | ||||
| ``` | ||||
|  | ||||
| * Configure jail.local | ||||
|  | ||||
| ``` | ||||
| cat <<'EOT' | tee /usr/local/etc/fail2ban/jail.local > /dev/null | ||||
| [DEFAULT] | ||||
| banaction = jail2ban-pf | ||||
| ``` | ||||
|  | ||||
| @ -42,6 +42,15 @@ def create_app(): | ||||
|                 check_password_hash(users.get(username), password): | ||||
|             return username | ||||
|  | ||||
|     @app.route("/ping", methods=['GET']) | ||||
|     @auth.login_required | ||||
|     def ping(): | ||||
|         remote_user = auth.username() | ||||
|         app.logger.info('Received ping for' | ||||
|                         f' anchor f2b-jail/{remote_user}') | ||||
|         return jsonify({'anchor': f'f2b-jail/{remote_user}', | ||||
|                         'operation': 'ping', | ||||
|                         'result': 'pong'}) | ||||
|     @app.route("/flush/<name>", methods=['GET']) | ||||
|     @auth.login_required | ||||
|     def flush(name): | ||||
|  | ||||
							
								
								
									
										10
									
								
								tests/test_ping.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/test_ping.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| def test_ping(client, mocker, valid_credentials): | ||||
|     ''' | ||||
|     Test application health check | ||||
|     ''' | ||||
|  | ||||
|     response = client.get("/ping", | ||||
|                           headers={"Authorization": | ||||
|                                    "Basic " + valid_credentials}) | ||||
|  | ||||
|     assert response.json['operation'] == 'ping' | ||||
		Reference in New Issue
	
	Block a user