--- /dev/null
+#!/bin/sh
+
+
+sleep 1
+systemctl --quiet is-active NetworkManager.service
+NM_RC=$?
+CYCLES_WAITED=0
+while [ $NM_RC -ne 0 ]
+do
+ if [ $CYCLES_WAITED -ge 10 ]
+ then
+ exit 1
+ fi
+ if [ $CYCLES_WAITED -eq 0 ]
+ then
+ echo -n "Waiting for NetworkManager"
+ fi
+ echo -n .
+ sleep 1
+ CYCLES_WAITED=$(( $CYCLES_WAITED + 1 ))
+ systemctl --quiet is-active NetworkManager.service
+ NM_RC=$?
+done
+[ $CYCLES_WAITED -gt 0 ] && echo
+
+# wait for one/the network connection to come up
+CONNECTION_DEVICES_UP=$(nmcli --terse connection show \
+ | grep --invert-match ':$' | wc -l)
+CYCLES_WAITED=0
+while [ $CONNECTION_DEVICES_UP -lt 1 ]
+do
+ if [ $CYCLES_WAITED -ge 10 ]
+ then
+ nmcli connection show
+ exit 1
+ fi
+ if [ $CYCLES_WAITED -eq 0 ]
+ then
+ echo -n "Waiting for the network connection"
+ fi
+ echo -n .
+ sleep 1
+ CYCLES_WAITED=$(( $CYCLES_WAITED + 1 ))
+ CONNECTION_DEVICES_UP=$(nmcli --terse connection show \
+ | grep --invert-match ':$' | wc -l)
+done
+[ $CYCLES_WAITED -gt 0 ] && echo
+
+CONNECTIONS=$(nmcli --terse connection show | wc -l)
+if [ $CONNECTIONS -ne 1 ]
+then
+ echo "Number of connections: $CONNECTIONS" >&2
+ exit 1
+fi
+
+CONNECTION_LINE=$(nmcli --terse connection show)
+CONNECTION_UUID=$(echo $CONNECTION_LINE | cut -f 2 -d ':')
+CONNECTION_DEVICE=$(echo $CONNECTION_LINE | cut -f 4 -d ':')
+
+nmcli connection delete uuid "$CONNECTION_UUID"
+
+nmcli connection add \
+ connection.autoconnect yes \
+ connection.id internal \
+ connection.interface-name $CONNECTION_DEVICE \
+ connection.type 802-3-ethernet \
+ ipv4.addresses "10.228.109.67/16" \
+ ipv4.dns "10.228.109.159, 10.228.92.159" \
+ ipv4.dns-search "in.useribm.hu" \
+ ipv4.gateway "10.228.109.254" \
+ ipv4.method "manual" \
+ ipv6.addresses "2a02:d400:0000:f268:000c:18ff:fe03:6d43/64" \
+ ipv6.dns "2a02:d400:0000:f268:000c:18ff:fe03:6d9f, 2a02:d400:0000:f268:000c:18ff:fe03:5c9f" \
+ ipv6.dns-search "in.useribm.hu" \
+ ipv6.gateway "2a02:d400:0000:f268:000c:18ff:fe03:6dfe" \
+ ipv6.method "manual" \
+ save yes
+
+nmcli connection show
--- /dev/null
+#!/bin/sh
+
+
+sleep 1
+systemctl --quiet is-active dbus.service
+DBUS_RC=$?
+WAITED=0
+while [ $DBUS_RC -ne 0 ]
+do
+ if [ $WAITED -eq 0 ]
+ then
+ echo -n "Waiting for dbus.service"
+ fi
+ echo -n .
+ sleep 1
+ WAITED=1
+ systemctl --quiet is-active dbus.service
+ DBUS_RC=$?
+done
+[ $WAITED -ne 0 ] && echo
+timedatectl set-timezone Europe/Budapest
--- /dev/null
+#!/bin/sh
+
+
+REAL_PATH=$(realpath $(dirname $0))
+
+
+authselect select sssd with-mkhomedir --force
+
+echo "URI ldaps://fds.useribm.hu/" >>/etc/openldap/ldap.conf
+echo "BASE dc=user,dc=hu" >>/etc/openldap/ldap.conf
--- /dev/null
+#!/bin/sh
+
+
+/usr/local/bin/getletsencrypt.sh
--- /dev/null
+#!/bin/sh
+
+
+if [ -d /etc/letsencrypt/live/useribm ]
+then
+ for ORIG_FILE in /etc/httpd/conf.d/*.le
+ do
+ CONF_FILE=$(echo $ORIG_FILE | sed 's/^\(.*\)\.le$/\1/')
+ echo "Moving $ORIG_FILE to $CONF_FILE"
+ mv $ORIG_FILE $CONF_FILE
+ done
+ cp --archive \
+ /usr/lib/python3.10/site-packages/certbot_apache/_internal/tls_configs/current-options-ssl-apache.conf \
+ /etc/letsencrypt/options-ssl-apache.conf
+ systemctl enable httpd.service
+ systemctl start httpd.service
+fi
--- /dev/null
+#!/bin/sh
+
+
+systemctl enable oddjobd.service
+systemctl start oddjobd.service
+systemctl enable sssd.service
+systemctl start sssd.service
+
+systemctl enable NetworkManager-wait-online.service
+systemctl start NetworkManager-wait-online.service
+
+systemctl enable logrotate.timer
+systemctl start logrotate.timer
--- /dev/null
+# mode file (relative to /c3d)
+755 firstboot/scripts/*.sh
+440 postinstall/install-data/etc/ssh/ssh_host_*_key
+444 postinstall/install-data/etc/ssh/ssh_host_*_key.pub
+600 postinstall/install-data/etc/ssh/sshd_config.d/*.conf
+600 postinstall/install-data/etc/sssd/sssd.conf
+755 postinstall/install-data/usr/local/bin/*.py
+755 postinstall/install-data/usr/local/bin/*.sh
+755 postinstall/scripts/*.sh
--- /dev/null
+# owner file (relative to /c3d)
+root.ssh_keys postinstall/install-data/etc/ssh/ssh_host_*_key
--- /dev/null
+WSGISocketPrefix run/wsgi
+
+<VirtualHost *:443>
+ ServerName fdc.useribm.hu
+ ServerAdmin siteadmin@useribm.hu
+ DocumentRoot "/var/www/htdocs.443"
+
+ SSLCertificateFile /etc/letsencrypt/live/useribm/fullchain.pem
+ SSLCertificateKeyFile /etc/letsencrypt/live/useribm/privkey.pem
+ Include /etc/letsencrypt/options-ssl-apache.conf
+
+ <Directory /var/www/htdocs.443>
+ DirectoryIndex index.xhtml
+ #Options FollowSymLinks Indexes
+ #IndexOptions Charset=UTF-8 NameWidth=*
+ <RequireAny>
+ Require all granted
+ </RequireAny>
+ </Directory>
+
+ DavLockDB /var/www/htdocs.443/dav/lock
+
+ WSGIDaemonProcess was.443 processes=1 threads=1 maximum-requests=10000 shutdown-timeout=5
+ WSGIProcessGroup was.443
+ WSGIScriptAlias /passwordchange /var/www/htdocs.443/wsgi/passwordchange.wsgi
+</VirtualHost>
--- /dev/null
+<VirtualHost *:80>
+ ServerName fdc.useribm.hu
+ ServerAdmin siteadmin@useribm.hu
+
+ Redirect permanent / https://fdc.useribm.hu/
+</VirtualHost>
--- /dev/null
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAe9DNoJPhMNt1ZHK9XsR1u9OST5FAcoHL9MVXarEDo3wAAAIj/fKw7/3ys
+OwAAAAtzc2gtZWQyNTUxOQAAACAe9DNoJPhMNt1ZHK9XsR1u9OST5FAcoHL9MVXarEDo3w
+AAAEDLDS0ZQeg6RdoS0O7UBBRL7eV2UR+WAt0vo6ICnCnDch70M2gk+Ew23Vkcr1exHW70
+5JPkUBygcv0xVdqsQOjfAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
--- /dev/null
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIDKU1Qv0xVQsBXFkQ7BLNDz41lny8emxGrAhdTvAWt/tAAAAIB70M2gk+Ew23Vkcr1exHW705JPkUBygcv0xVdqsQOjfAAAAAAAAAAAAAAACAAAADmZkYy51c2VyaWJtLmh1AAAAEgAAAA5mZGMudXNlcmlibS5odQAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIEXYIIzrUSx8/BQ6/ttkSr5oEyB5F5Yg4bp1DOkqDON9AAAAUwAAAAtzc2gtZWQyNTUxOQAAAEDPGYtr8L8QZkualco2Bhh2oT8QpU9IDvAdnSBp5kEpdpksiL2j/8YUUZ/E1fys2Tk/Q/eoyb31K6peYuiOjAAK ssh_host_ed25519_key.pub
--- /dev/null
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB70M2gk+Ew23Vkcr1exHW705JPkUBygcv0xVdqsQOjf
--- /dev/null
+HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
--- /dev/null
+TrustedUserCAKeys /etc/ssh/trusted-user-ca.keys
--- /dev/null
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICcf/XXU8dNVtbveGmwbdnRJfYIItzxKmgRkzlp0k6r5 user-CA
--- /dev/null
+[sssd]
+services = nss, pam
+domains = ldap
+
+[nss]
+default_shell = /bin/bash
+
+[pam]
+
+[domain/ldap]
+id_provider = ldap
+ldap_uri = ldaps://fds.useribm.hu
+ldap_search_base = dc=user,dc=hu
+ldap_tls_cacertdir = /etc/openldap/certs
+ldap_tls_reqcert = allow
+
+auth_provider = ldap
+chpass_provider = ldap
+
+cache_credentials = True
--- /dev/null
+#!/bin/sh
+
+
+if [ -d /etc/letsencrypt ]
+then
+ rm --force --recursive /etc/letsencrypt.old
+ cp --archive /etc/letsencrypt /etc/letsencrypt.old
+fi
+
+/usr/bin/rsync \
+ --archive \
+ --delete-after \
+ --info=STATS \
+ pki.in.useribm.hu::letsencrypt \
+ /etc/letsencrypt
+
+cp --archive \
+ /usr/lib/python3.10/site-packages/certbot_apache/_internal/tls_configs/current-options-ssl-apache.conf \
+ /etc/letsencrypt/options-ssl-apache.conf
--- /dev/null
+#!/usr/bin/env python
+
+
+import ldap
+import time
+
+
+LDAP_URI='ldaps://fds.useribm.hu'
+USERS_BASE='ou=people,dc=user,dc=hu'
+
+
+if __name__ == '__main__':
+
+ ldap_object = ldap.initialize(LDAP_URI)
+ #ldap_object.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
+ #ldap_object.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
+
+ search_id = ldap_object.search(USERS_BASE, ldap.SCOPE_SUBTREE, attrlist=['uid', 'pwdUpdateTime'])
+ (search_result_type, search_result_data) = ldap_object.result()
+
+ current_timestamp = time.mktime(time.gmtime())
+ for item in search_result_data:
+ (dn, values) = item
+ if 'pwdUpdateTime' in values:
+ uid = values['uid'][0].decode('utf-8')
+ pwdupdatetime = values['pwdUpdateTime'][0].decode('utf-8')
+ pwdupdatetimestamp = time.mktime(time.strptime(pwdupdatetime, '%Y%m%d%H%M%S%z'))
+ days_since_password_update = (current_timestamp - pwdupdatetimestamp) / (24 * 60 * 60)
+ print(uid, pwdupdatetime, days_since_password_update)
+ #print(dn, values)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Password Change</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+ <link rel="stylesheet" href="main.css" type="text/css" />
+ </head>
+ <body>
+ <form action="/passwordchange" method="post">
+ <p>Login Name:</p>
+ <p><input name="login_name" type="text" /></p>
+ <p>Old Password:</p>
+ <p><input name="old_password" type="password" /></p>
+ <hr />
+ <p>New Password:</p>
+ <p><input name="new_password" type="password" /></p>
+ <p>New Password Again:</p>
+ <p><input name="new_password_again" type="password" /></p>
+ <p><input type="submit" value="Change" /></p>
+ </form>
+ </body>
+</html>
--- /dev/null
+h1, p {
+ /* Center horizontally*/
+ text-align: center;
+}
--- /dev/null
+ </body>
+</html>
--- /dev/null
+import os
+import cgi
+import sys
+import ldap
+import traceback
+
+
+LDAP_URI='ldaps://fds.useribm.hu'
+USERS_BASE='ou=people,dc=user,dc=hu'
+
+
+def password_change_app(environ, start_response):
+
+ error_occured = False
+
+ field_storage = cgi.FieldStorage(fp=environ['wsgi.input'],
+ environ=environ,
+ keep_blank_values=True)
+
+ uid = field_storage['login_name'].value
+ old_password = field_storage['old_password'].value
+ new_password = field_storage['new_password'].value
+ new_password_again = field_storage['new_password_again'].value
+
+ if new_password != new_password_again:
+ formatted_traceback = ['NEW_PASSWORD_MISMATCH']
+ error_occured = True
+
+ if not error_occured:
+ try:
+ ldap_object = ldap.initialize(LDAP_URI)
+ #ldap_object.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
+ #ldap_object.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
+ except:
+ (exc_type, exc_value, exc_traceback) = sys.exc_info()
+ formatted_traceback = traceback.format_exception(exc_type,
+ exc_value,
+ exc_traceback)
+ error_occured = True
+
+ if not error_occured:
+ user_dn=','.join(['uid={}'.format(uid), USERS_BASE])
+ try:
+ bind_id = ldap_object.simple_bind(user_dn, old_password)
+ (bind_result_type, bind_result_data) = ldap_object.result()
+ except:
+ (exc_type, exc_value, exc_traceback) = sys.exc_info()
+ formatted_traceback = traceback.format_exception(exc_type,
+ exc_value,
+ exc_traceback)
+ error_occured = True
+
+ if not error_occured:
+ try:
+ password_change_id = ldap_object.passwd(user_dn,
+ old_password,
+ new_password)
+ (pwd_result_type, pwd_result_data) = ldap_object.result()
+ except:
+ (exc_type, exc_value, exc_traceback) = sys.exc_info()
+ formatted_traceback = traceback.format_exception(exc_type,
+ exc_value,
+ exc_traceback)
+ error_occured = True
+
+ prologue_file = open('/var/www/htdocs.443/wsgi/prologue.xhtml', 'r')
+ response_prologue = prologue_file.read()
+ prologue_file.close()
+ response_epilogue = '</body></html>'
+ if not error_occured:
+ success_text = '<h1>Woohoo, you have successfully changed your password!</h1>'
+ response_texts = [response_prologue,
+ success_text,
+ response_epilogue]
+ else:
+ response_texts = [response_prologue, '<pre>']
+ response_texts.extend(formatted_traceback)
+ response_texts.append('</pre>')
+ response_texts.append('<p><button onclick="history.back()">Go Back and Try Again</button></p>')
+ response_texts.append(response_epilogue)
+ response_body = bytes(os.linesep.join(response_texts), 'utf-8')
+
+ # HTTP response code and message
+ status = '200 OK'
+
+ # HTTP headers expected by the client
+ # They must be wrapped as a list of tupled pairs:
+ # [(Header name, Header value)].
+ response_headers = [
+ ('Content-Type', 'text/html'),
+ ('Content-Length', str(len(response_body)))
+ ]
+
+ # Send them to the server using the supplied function
+ start_response(status, response_headers)
+
+ # Return the response body. Notice it is wrapped
+ # in a list although it could be any iterable.
+ return [response_body]
+
+application = password_change_app
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Password Change</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" href="main.css" type="text/css" />
+ </head>
+ <body>
--- /dev/null
+#!/bin/sh
+
+
+systemctl disable httpd.service
+systemctl disable oddjobd.service
+systemctl disable sssd.service
+
+systemctl disable NetworkManager-wait-online.service
+
+systemctl disable logrotate.timer
--- /dev/null
+lxc.include = /usr/share/lxc/config/common.conf
+
+lxc.arch = x86_64
+lxc.uts.name = fdc.useribm.hu
+lxc.rootfs.path = __CONTAINER_PATH__/rootfs
+lxc.mount.auto = proc:rw sys:ro
+
+lxc.net.0.type = veth
+lxc.net.0.flags = up
+lxc.net.0.link = brci-dev
+lxc.net.0.hwaddr = 02:0c:18:03:6d:43
+
+lxc.autodev = 1
+
+lxc.cgroup2.devices.allow = a
+
+lxc.signal.halt = SIGRTMIN+4
+
+lxc.start.auto = 1
+lxc.start.order = __CONTAINER_START_ORDER__
+lxc.start.delay = 5
--- /dev/null
+DISTRIBUTION=Fedora
+DISTRIBUTION_VERSION=35
+SPEC_PACKAGES="authselect cronie httpd mailx mod_ssl oddjob-mkhomedir"
+SPEC_PACKAGES="$SPEC_PACKAGES openldap-clients openssh-clients"
+SPEC_PACKAGES="$SPEC_PACKAGES openssh-server passwd python3-certbot-apache"
+SPEC_PACKAGES="$SPEC_PACKAGES python3-ldap python3-mod_wsgi rsync sssd-ldap"