bundlewrap/libs/systemd.py

93 lines
2.4 KiB
Python

from mako.template import Template
template = '''
% for segment, options in data.items():
% if '#' in segment:
# ${segment.split('#', 2)[1]}
% endif
[${segment.split('#')[0]}]
% for option, value in sorted(options.items()):
% if isinstance(value, dict):
% for k, v in value.items():
${option}=${k}=${v}
% endfor
% elif isinstance(value, (list, set, tuple)):
% for item in (sorted(value) if isinstance(value, set) else value):
${option}=${item}
% endfor
% elif isinstance(value, type(None)):
% else:
${option}=${str(value)}
% endif
% endfor
% endfor
'''
order = [
'Unit',
'Timer',
'Service',
'Swap',
'Install',
]
def segment_order(segment):
return (
order.index(segment[0]) if segment[0] in order else float('inf'),
segment[0]
)
def generate_unitfile(data):
return Template(template).render(
data=dict(sorted(data.items(), key=segment_order)),
).lstrip()
# wip
def protection():
return {
# user
'UMask': '077',
'DynamicUser': 'yes',
'PrivateUsers': 'yes',
'RestrictSUIDSGID': 'yes',
'NoNewPrivileges': 'yes',
'LockPersonality': 'yes',
'RemoveIPC': 'yes',
# fs
'ProtectSystem': 'strict',
'ProtectHome': 'yes',
'PrivateTmp': 'yes',
'PrivateDevices': 'yes',
'ProtectProc': 'invisible',
'ProcSubset': 'pid',
'PrivateMounts': 'yes',
'RestrictFileSystems': {'ext4', 'tmpfs', 'zfs'},
'NoExecPaths': {'/'},
'ExecPaths': {'/bin', '/sbin', '/lib', '/lib64', '/usr'},
'TemporaryFileSystem': {'/var'},
# network
'IPAddressDeny': 'any',
'PrivateNetwork': 'yes',
'RestrictAddressFamilies': 'none',
# syscall
'SystemCallArchitectures': 'native',
'SystemCallFilter': '~@swap @resources @reboot @raw-io @privileged @obsolete @mount @module @debug @cpu-emulation @clock',
# else
'ProtectHostname': 'yes',
'ProtectClock': 'yes',
'ProtectKernelTunables': 'yes',
'ProtectKernelModules': 'yes',
'ProtectKernelLogs': 'yes',
'ProtectControlGroups': 'yes',
'RestrictNamespaces': 'yes',
'MemoryDenyWriteExecute': 'yes',
'RestrictRealtime': 'yes',
'CapabilityBoundingSet': '',
}