mirror of
https://codeberg.org/prof_x_pvt_ltd/captive.whump.shanti-portal
synced 2024-08-14 22:46:42 +00:00
Merge branch 'master' into rs
This commit is contained in:
commit
c3c709785b
6 changed files with 73 additions and 8 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,4 +5,4 @@
|
|||
build/
|
||||
dist/
|
||||
*.egg-info
|
||||
keep_local.cfg
|
||||
*_local.cfg
|
||||
|
|
32
README.md
32
README.md
|
@ -45,3 +45,35 @@ Also with plugins there are options to connect other authentication methods like
|
|||
# Deployment
|
||||
|
||||
See examples in docs/examples directory.
|
||||
|
||||
# Technical details
|
||||
|
||||
## IPtables
|
||||
|
||||
At the heart is iptables doing the following.
|
||||
|
||||
1. Labeling all traffic with the number 99 in the mangle table.
|
||||
2. Labeled ICMP, DNS and HTTP traffic is redirected to the portal server in the nat table.
|
||||
3. All other labeled traffic is dropped.
|
||||
4. Authenticated clients are jumped out of the mangle table before being labeled, using the RETURN target.
|
||||
5. Authenticated clients are also deleted from conntrack after having their exception rules created in the mangle table.
|
||||
|
||||
## Portal
|
||||
|
||||
All this is of course triggered by the portal application written in Python using Bottle.
|
||||
|
||||
1. A clients redirected HTTP traffic puts them in the portal webpage.
|
||||
2. They send a POST form to the /approve url. This can be with user info, personal info, or simply an approve button for a EULA.
|
||||
3. The portal executes its plugins in the order that their config section appears in plugins.cfg.
|
||||
4. Each plugin is passed the request object from Bottle which contains form values among other things.
|
||||
|
||||
## Plugins
|
||||
|
||||
There's only one relevant plugin right now, iptables. But the idea is that you could add RADIUS plugins or other services. The mandatory flag in plugins.cfg decides if a plugin must pass before a client is authenticated. So you can string several plugins together for several actions that must be performed.
|
||||
|
||||
Each plugin responds with JSON.
|
||||
|
||||
### iptables plugin
|
||||
|
||||
1. Executes the ``iptables_cmd`` defined in plugins.cfg, with arguments being the client IP and potentially the client MAC address.
|
||||
2. Ensures the exit code of ``iptables_cmd`` is 0, if not 0 it sets a failed flag in its JSON response.
|
||||
|
|
3
plugins/README.md
Normal file
3
plugins/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# iptables plugin
|
||||
|
||||
Mac address discovery using arping is not always reliable in large complex networks.
|
|
@ -4,6 +4,8 @@ import json
|
|||
from pprint import pprint as pp
|
||||
from uuid import UUID
|
||||
from importlib import import_module
|
||||
from logging import Formatter, getLogger, DEBUG, INFO, WARN
|
||||
from logging.handlers import SysLogHandler, RotatingFileHandler
|
||||
|
||||
# Until pyvenv-3.4 is fixed on centos 7 support python 2.
|
||||
try:
|
||||
|
@ -11,9 +13,6 @@ try:
|
|||
except ImportError:
|
||||
from ConfigParser import RawConfigParser
|
||||
|
||||
from logging import Formatter, getLogger, DEBUG, INFO, WARN
|
||||
from logging.handlers import SysLogHandler, RotatingFileHandler
|
||||
|
||||
from redis import Redis
|
||||
from rq import Queue
|
||||
from bottle import Bottle, default_app
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
--index-url https://pypi.python.org/simple/
|
||||
|
||||
-e
|
||||
# TODO: Fix this.
|
||||
rq
|
||||
redis
|
||||
Bottle
|
||||
sh
|
||||
python-iptables
|
||||
|
|
30
tools/add_client.py
Normal file
30
tools/add_client.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from pprint import pprint as pp
|
||||
|
||||
import iptc
|
||||
|
||||
parser = ArgumentParser()
|
||||
|
||||
parser.add_argument('--chain', required=True)
|
||||
parser.add_argument('--protocol', required=True)
|
||||
parser.add_argument('--src-ip', required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
table = iptc.Table(iptc.Table.MANGLE)
|
||||
chain = iptc.Chain(table, args.chain)
|
||||
|
||||
# Check if rule exists
|
||||
for rule in chain.rules:
|
||||
src_ip = rule.src
|
||||
if src_ip.startswith(args.src_ip):
|
||||
print('Rule exists')
|
||||
break
|
||||
else:
|
||||
rule = iptc.Rule()
|
||||
rule.src = args.src_ip
|
||||
rule.protocol = args.protocol
|
||||
rule.target = iptc.Target(rule, 'RETURN')
|
||||
chain.insert_rule(rule)
|
Loading…
Reference in a new issue