Initial commit

This commit is contained in:
lordwelch 2022-04-26 15:54:25 -07:00
commit d8bec448ad
14 changed files with 899 additions and 0 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
freepydius.py
venv
def
policies
requirements.txt
*.ipt
*.acl

4
.flake8 Normal file
View File

@ -0,0 +1,4 @@
[flake8]
max-line-length = 120
extend-ignore = E203, E501, E722
extend-exclude = venv

262
.gitignore vendored Normal file
View File

@ -0,0 +1,262 @@
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Cache files for Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
# Workspace files are user-specific
*.sublime-workspace
# Project files should be checked into the repository, unless a significant
# proportion of contributors will probably not be using Sublime Text
# *.sublime-project
# SFTP configuration file
sftp-config.json
sftp-config-alt*.json
# Package control specific files
Package Control.last-run
Package Control.ca-list
Package Control.ca-bundle
Package Control.system-ca-bundle
Package Control.cache/
Package Control.ca-certs/
Package Control.merged-ca-bundle
Package Control.user-ca-bundle
oscrypto-ca-bundle.crt
bh_unicode_properties.cache
# Sublime-github package stores a github token in this file
# https://packagecontrol.io/packages/sublime-github
GitHub.sublime-settings
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
# acl files
*.acl
*.ipt

36
Dockerfile Normal file
View File

@ -0,0 +1,36 @@
FROM ghcr.io/linuxserver/baseimage-alpine:3.15
# set version label
ARG BUILD_DATE
ARG VERSION
ARG FREERADIUS_VERSION
LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}"
LABEL maintainer="lordwelch"
# install packages
RUN \
apk add --no-cache --upgrade \
freeradius-python3 py3-paho-mqtt py3-netaddr && \
sed -i -e 's@/etc@/config@g' -e '/\suser =\|\sgroup =/s/^/#/g' -e 's@/var/log@/config/log/freeradius@g'\
/etc/raddb/radiusd.conf
##DO STUFF HERE
## END EACH LINE WITH && \
## EXCEPT THE LAST LINE OF THE BLOCK
# add local files
COPY root/ /
# ports and volumes
EXPOSE 1812/udp 1813/udp
VOLUME /config
## NOTES ##
## Delete files\folders not needed
## The User abc, should be running everything, give that permission in any case you need it.
## When creating init's Use 10's where posible, its to allow add stuff in between when needed. also, do not be afraid to split custom code into several little ones.
## user abc and folders /app /config /defaults are all created by baseimage
## the first available init script is 30<your script>
## you can comment the beginning of each new RUN block but you cannot comment between commands in each RUN block.

205
def/NETWORK.net Normal file
View File

@ -0,0 +1,205 @@
#
# Sample naming defintions for network objects
#
RFC1918 = 10.0.0.0/8 # non-public
172.16.0.0/12 # non-public
192.168.0.0/16 # non-public
INTERNAL = RFC1918
LOOPBACK = 127.0.0.0/8 # loopback
::1/128 # ipv6 loopback
RFC_3330 = 169.254.0.0/16 # special use IPv4 addresses - netdeploy
RFC_6598 = 100.64.0.0/10 # Shared Address Space
LINKLOCAL = FE80::/10 # IPv6 link-local
SITELOCAL = FEC0::/10 # Ipv6 Site-local
MULTICAST = 224.0.0.0/4 # IP multicast
FF00::/8 # IPv6 multicast
CLASS-E = 240.0.0.0/4
RESERVED = 0.0.0.0/8 # reserved
RFC1918
LOOPBACK
RFC_3330
RFC_6598
MULTICAST
CLASS-E
0000::/8 # reserved by IETF
0100::/8 # reserved by IETF
0200::/7 # reserved by IETF
0400::/6 # reserved by IETF
0800::/5 # reserved by IETF
1000::/4 # reserved by IETF
4000::/3 # reserved by IETF
6000::/3 # reserved by IETF
8000::/3 # reserved by IETF
A000::/3 # reserved by IETF
C000::/3 # reserved by IETF
E000::/4 # reserved by IETF
F000::/5 # reserved by IETF
F800::/6 # reserved by IETF
FC00::/7 # unique local unicast
FE00::/9 # reserved by IETF
LINKLOCAL # link local unicast
SITELOCAL # IPv6 site-local
PUBLIC = 1.0.0.0/8
2.0.0.0/7
4.0.0.0/6
8.0.0.0/7
11.0.0.0/8
12.0.0.0/6
16.0.0.0/4
32.0.0.0/3
64.0.0.0/3
96.0.0.0/6
100.0.0.0/10
100.128.0.0/9
101.0.0.0/8
102.0.0.0/7
104.0.0.0/5
112.0.0.0/5
120.0.0.0/6
124.0.0.0/7
126.0.0.0/8
128.0.0.0/3
160.0.0.0/5
168.0.0.0/8
169.0.0.0/9
169.128.0.0/10
169.192.0.0/11
169.224.0.0/12
169.240.0.0/13
169.248.0.0/14
169.252.0.0/15
169.255.0.0/16
170.0.0.0/7
172.0.0.0/12
172.32.0.0/11
172.64.0.0/10
172.128.0.0/9
173.0.0.0/8
174.0.0.0/7
176.0.0.0/4
192.0.1.0/24
192.0.3.0/24
192.0.4.0/22
192.0.8.0/21
192.0.16.0/20
192.0.32.0/19
192.0.64.0/18
192.0.128.0/17
192.1.0.0/16
192.2.0.0/15
192.4.0.0/14
192.8.0.0/13
192.16.0.0/12
192.32.0.0/11
192.64.0.0/10
192.128.0.0/11
192.160.0.0/13
192.169.0.0/16
192.170.0.0/15
192.172.0.0/14
192.176.0.0/12
192.192.0.0/10
193.0.0.0/8
194.0.0.0/7
196.0.0.0/7
198.0.0.0/12
198.16.0.0/15
198.20.0.0/14
198.24.0.0/13
198.32.0.0/12
198.48.0.0/15
198.50.0.0/16
198.51.0.0/18
198.51.64.0/19
198.51.96.0/22
198.51.101.0/24
198.51.102.0/23
198.51.104.0/21
198.51.112.0/20
198.51.128.0/17
198.52.0.0/14
198.56.0.0/13
198.64.0.0/10
198.128.0.0/9
199.0.0.0/8
200.0.0.0/7
202.0.0.0/8
203.0.0.0/18
203.0.64.0/19
203.0.96.0/20
203.0.112.0/24
203.0.114.0/23
203.0.116.0/22
203.0.120.0/21
203.0.128.0/17
203.1.0.0/16
203.2.0.0/15
203.4.0.0/14
203.8.0.0/13
203.16.0.0/12
203.32.0.0/11
203.64.0.0/10
203.128.0.0/9
204.0.0.0/6
208.0.0.0/4
ANY = 0.0.0.0/0
ANY_V6 = ::/0
ANY_MIXED = ANY
ANY_V6
# http://www.team-cymru.org/Services/Bogons/bogon-bn-agg.txt
# 22-Apr-2011
BOGON = 0.0.0.0/8
192.0.0.0/24
192.0.2.0/24
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
MULTICAST
CLASS-E
3FFE::/16 # 6bone
5F00::/8 # 6bone
2001:DB8::/32 # IPv6 documentation prefix
GOOGLE_PUBLIC_DNS_ANYCAST = 8.8.4.4/32 # IPv4 Anycast
8.8.8.8/32 # IPv4 Anycast
2001:4860:4860::8844/128 # IPv6 Anycast
2001:4860:4860::8888/128 # IPv6 Anycast
GOOGLE_DNS = GOOGLE_PUBLIC_DNS_ANYCAST
# The following are sample entires intended for us in the included
# sample policy file. These should be removed.
MANAGEMENT_SERVERS = 192.168.0.1/32
192.168.0.44/32
192.168.0.46/32
MAIL_SERVERS = 200.1.1.4/32 # Example mail server 1
200.1.1.5/32 # Example mail server 2
PUBLIC_NAT = 200.1.1.3/32 # Example company NAT address
NTP_SERVERS = 10.0.0.1/32 # Example NTP server
10.0.0.2/32 # Example NTP server
TACACS_SERVERS = 10.1.0.1/32 # Example tacacs server
10.1.0.2/32 # Example tacacs server
PUBLIC_IPV6_SERVERS = 2606:700:e:550:b01a::b00a # Example public web server
WEB_IPV6_SERVERS = 2620:15c:2c4:202:b0e7:158f:6a7a:3188/128 # Example web server

64
def/SERVICES.svc Normal file
View File

@ -0,0 +1,64 @@
#
# Sample naming service definitions
#
WHOIS = 43/udp
SSH = 22/tcp
TELNET = 23/tcp
SMTP = 25/tcp
MAIL_SERVICES = SMTP
ESMTP
SMTP_SSL
POP_SSL
TIME = 37/tcp 37/udp
TACACS = 49/tcp
DNS = 53/tcp 53/udp
BOOTPS = 67/udp # BOOTP server
BOOTPC = 68/udp # BOOTP client
DHCP = BOOTPS
BOOTPC
TFTP = 69/tcp 69/udp
HTTP = 80/tcp
WEB_SERVICES = HTTP HTTPS
POP3 = 110/tcp
RPC = 111/udp
IDENT = 113/tcp 113/udp
NNTP = 119/tcp
NTP = 123/tcp 123/udp
MS_RPC_EPMAP = 135/udp 135/tcp
MS_137 = 137/udp
MS_138 = 138/udp
MS_139 = 139/tcp
IMAP = 143/tcp
SNMP = 161/udp
SNMP_TRAP = 162/udp
BGP = 179/tcp
IMAP3 = 220/tcp
LDAP = 389/tcp
LDAP_SERVICE = LDAP
LDAPS
HTTPS = 443/tcp
MS_445 = 445/tcp
SMTP_SSL = 465/tcp
IKE = 500/udp
SYSLOG = 514/udp
RTSP = 554/tcp
ESMTP = 587/tcp
LDAPS = 636/tcp
IMAPS = 993/tcp
POP_SSL = 995/tcp
HIGH_PORTS = 1024-65535/tcp 1024-65535/udp
MSSQL = 1433/tcp
MSSQL_MONITOR = 1434/tcp
RADIUS = 1812/tcp 1812/udp
HSRP = 1985/udp
NFSD = 2049/tcp 2049/udp
NETFLOW = 2056/udp
SQUID_PROXY = 3128/tcp
MYSQL = 3306/tcp
RDP = 3389/tcp
IPSEC = 4500/udp
POSTGRESQL = 5432/tcp
TRACEROUTE = 33434-33534/udp
MGMT = SSH 23/tcp 441/tcp 442/tcp

125
freepydius.py Normal file
View File

@ -0,0 +1,125 @@
import json
import os
import os.path
from collections import defaultdict
import netaddr
import paho.mqtt.client as mqtt
import radiusd
def log(level, s):
"""Log function."""
radiusd.radlog(level, __name__ + ": " + s)
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("router7/#")
def get_leases():
msgs = defaultdict(lambda: defaultdict(str))
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
lease = json.loads(msg.payload)
lease["identifier"] = os.path.basename(msg.topic)
msgs[lease["identifier"]] = defaultdict(str, lease)
client = mqtt.Client()
client.username_pw_set(os.getenv("MQTT_USERNAME"), os.getenv("MQTT_PASSWORD"))
client.on_connect = on_connect
client.on_message = on_message
client.connect("hassio.narnian.us", 1883, 60)
cont = True
count = 0
while cont:
client.loop(timeout=0.5)
client.loop(timeout=0.5)
client.loop(timeout=0.5)
client.loop(timeout=0.5)
if count == len(msgs):
break
count = len(msgs)
return msgs
def select_acls(lease):
acls = []
if lease["vendor_identifier"].contains("PS4"):
acls.append("DENY")
acls.append("WEB")
return acls
def ciscoize_acl_names(acls):
cisco = []
for acl in acls:
cisco.append(
tuple(
"Cisco-AVPair",
"+=",
f"ACS:CiscoSecure-Defined-ACL=#ACSACL#-${acl}-fuckcisc",
)
)
return cisco
def deciscoize_acl_name(acl_name):
return acl_name.split("#ACSACL#-")[1][0:-9]
def get_acl(acl_name):
with open(acl_name, encoding="utf-8") as f:
return f.read()
def authorize(p):
os.chdir(os.path.dirname(__file__))
log(radiusd.L_INFO, str(p))
print("*** authorize ***")
print("")
radiusd.radlog(radiusd.L_INFO, "*** radlog call in authorize ***")
print("")
print(p)
print("")
print(radiusd.config)
print("")
request = defaultdict(str, p["request"])
reply = [
("User-Name", request["User-Name"]),
]
if netaddr.valid_mac(request["User-Name"]):
leases = get_leases()
reply.extend(ciscoize_acl_names(select_acls(leases[request["User-Name"]])))
elif "#ACSACL#" in request["User-Name"]:
deciscoize_acl_name(request["User-Name"])
conf = [
("Auth-Type", "Accept"),
]
log(radiusd.L_INFO, str(reply))
log(radiusd.L_INFO, str(conf))
return (radiusd.RLM_MODULE_OK, tuple(reply), tuple(conf))
def authenticate(p):
os.chdir(os.path.dirname(__file__))
log(radiusd.L_INFO, str(p))
radiusd.radlog(radiusd.L_INFO, "*** radlog call in authenticate ***")
print("")
print(p)
print("")
print(radiusd.config)
return radiusd.RLM_MODULE_OK

View File

@ -0,0 +1,114 @@
#
# This is an example policy for capirca
#
header {
comment:: "this is a sample edge input filter that generates"
comment:: "multiple output formats."
# NOTES: iptables produces filter 'lines' that must be used as args to the
# '$ iptables' cmd, while Speedway produces stateful iptables filters
# compatible with iptables-restore (most people will prefer speedway)
target:: cisco default-web extended
target:: speedway INPUT
}
# #include 'includes/untrusted-networks-blocking.inc'
term permit-web-services {
# destination-address:: WEB_SERVERS
protocol:: tcp
destination-port:: WEB_SERVICES
action:: accept
}
header {
target:: cisco windows extended
}
term accept-dhcp {
comment:: "Optional - allow DHCP requests."
destination-port:: DHCP
protocol:: udp
action:: accept
}
term accept-dns {
destination-port:: DNS
protocol:: tcp udp
action:: accept
}
term accept-icmp {
protocol:: icmp
action:: accept
}
term default-deny {
action:: deny
}
header {
target:: cisco accept-internal-ssh extended
}
term accept-public-ssh {
destination-address:: PUBLIC
protocol:: tcp
destination-port:: SSH
action:: accept
}
header {
target:: cisco accept-internal-ssh extended
}
term allow-internal-ssh {
destination-address:: INTERNAL
protocol:: tcp
destination-port:: SSH
action:: accept
}
header {
target:: cisco accept-mgmt-ssh extended
}
term allow-mgmt-ssh {
destination-address:: MANAGEMENT_SERVERS
protocol:: tcp
destination-port:: MGMT
action:: accept
}
# term permit-tcp-established {
# destination-address:: MAIL_SERVERS WEB_SERVERS PUBLIC_NAT
# protocol:: tcp
# option:: tcp-established
# action:: accept
# }
# term permit-udp-established {
# destination-address:: MAIL_SERVERS WEB_SERVERS PUBLIC_NAT
# protocol:: udp
# source-port:: HIGH_PORTS
# action:: accept
# }
# header {
# comment:: "this is a sample output filter"
# target:: cisco edge-outbound extended
# target:: speedway OUTPUT
# }
# term deny-to-bad-destinations {
# destination-address:: RFC1918 BOGON RESERVED
# action:: deny
# }
# term default-accept {
# action:: accept
# }

12
pyproject.toml Normal file
View File

@ -0,0 +1,12 @@
[tool.black]
line-length = 120
[tool.isort]
line_length = 120
profile = "black"
[tool.pylint.messages_control]
disable = "C0330, C0326, C0115, C0116, C0103"
[tool.pylint.format]
max-line-length=120

6
requirements.txt Normal file
View File

@ -0,0 +1,6 @@
isort>=5.10
black>=22
flake8==4.*
flake8-encodings
netaddr==0.8.*
paho-mqtt==1.6.*

View File

@ -0,0 +1,7 @@
#!/usr/bin/with-contenv bash
# make folders
mkdir -p \
/config/log/freeradius \
/config/raddb/
chown -R abc:abc /config/log

View File

@ -0,0 +1,42 @@
#!/usr/bin/with-contenv bash
migrate(){
local OLD_LOCATION="${1}"
local NEW_LOCATION="${2}"
if [[ -e ${OLD_LOCATION} ]];then
if [[ ! -e ${NEW_LOCATION} ]];then
echo "moving to ${NEW_LOCATION}"
cp -drT "${OLD_LOCATION}" "${NEW_LOCATION}"
fi
fi
}
migrate_dir(){
local OLD_LOCATION="${1}"
local NEW_LOCATION="${2}"
mkdir -p "${NEW_LOCATION}"
for f in "${OLD_LOCATION}/"*; do
migrate "${f}" "${NEW_LOCATION}/${f#$OLD_LOCATION/}"
done
}
migrate /etc/raddb/README.rst /config/raddb/README.rst
migrate /etc/raddb/clients.conf /config/raddb/clients.conf
migrate /etc/raddb/dictionary /config/raddb/dictionary
migrate /etc/raddb/panic.gdb /config/raddb/panic.gdb
migrate /etc/raddb/proxy.conf /config/raddb/proxy.conf
migrate /etc/raddb/radiusd.conf /config/raddb/radiusd.conf
migrate /etc/raddb/templates.conf /config/raddb/templates.conf
migrate /etc/raddb/trigger.conf /config/raddb/trigger.conf
migrate /etc/raddb/mods-enabled /config/raddb/mods-enabled
migrate /etc/raddb/sites-enabled /config/raddb/sites-enabled
migrate_dir /etc/raddb/certs /config/raddb/certs
migrate_dir /etc/raddb/policy.d /config/raddb/policy.d
migrate_dir /etc/raddb/mods-available /config/raddb/mods-available
migrate_dir /etc/raddb/mods-config /config/raddb/mods-config
migrate_dir /etc/raddb/sites-available /config/raddb/sites-available
chown -R abc:abc /config

View File

@ -0,0 +1,5 @@
#!/usr/bin/execlineb -S1
if { s6-test ${1} -ne 0 }
if { s6-test ${1} -ne 256 }
s6-svscanctl -t /var/run/s6/services

View File

@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash
# parse env vars to options
OPTIONS=""
if [[ ${FREERADIUS_DEBUG} && ${FREERADIUS_DEBUG-x} ]]; then
OPTIONS+="-X "
fi
exec \
s6-setuidgid abc /usr/sbin/radiusd -l stdout -f -d /config/raddb ${OPTIONS}