Initial commit
authorRalf Jung <post@ralfj.de>
Thu, 13 Feb 2014 14:35:32 +0000 (15:35 +0100)
committerRalf Jung <post@ralfj.de>
Thu, 13 Feb 2014 14:35:32 +0000 (15:35 +0100)
Makefile [new file with mode: 0644]
makeschsh [new file with mode: 0755]
schroot/user/copyfiles [new file with mode: 0644]
schroot/user/nssdatabases [new file with mode: 0644]
schsh [new file with mode: 0755]
sshd_config [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..bd9e5b0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+TARGET := /usr/local
+SCHROOT := /etc/schroot
+
+install:
+       install -o root -g root schsh makeschsh $(TARGET)/bin/
+       install -o root -g root -d $(SCHROOT)/user/
+       install -o root -g root -m 644 schroot/user/* $(SCHROOT)/user/
diff --git a/makeschsh b/makeschsh
new file mode 100755 (executable)
index 0000000..0dbb0aa
--- /dev/null
+++ b/makeschsh
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+# Configuration
+schsh = "/usr/local/bin/schsh"
+group = "schsh"
+chroots = "/var/lib/schsh"
+
+# END of Configuration
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+# DO NOT TOUCH ANYTHING BELOW THIS LINE
+
+import os, sys, subprocess, pwd, grp
+
+if os.getuid() != 0:
+       print "Run this a root, please."
+       sys.exit(1)
+
+
+def setup(name):
+       chroot = os.path.join(chroots, name)
+       if os.path.exists(chroot):
+               raise Exception(chroot+" already exists, please remove it first")
+       userpw = pwd.getpwnam(name)
+       
+       # schroot configuration
+       with open("/etc/schroot/chroot.d/user-"+name, "w") as f:
+               print >>f, """[user-{0}]
+type=directory
+directory={1}
+users={0}
+profile=user
+setup.fstab=user/user-{0}.fstab
+""".format(name, chroot)
+       with open("/etc/schroot/user/user-"+name+".fstab", "w") as f:
+               print >>f, """# <file system> <mount point>   <type>  <options>       <dump>  <pass>
+/bin          \t/bin          \tnone  \trw,bind       \t0     \t0
+/lib          \t/lib          \tnone  \trw,bind       \t0     \t0
+/usr/bin      \t/usr/bin      \tnone  \trw,bind       \t0     \t0
+/usr/lib      \t/usr/lib      \tnone  \trw,bind       \t0     \t0
+/home/{0}/data\t/data         \tnone  \trw,bind       \t0     \t0
+""".replace(' ', '').format(name) # need to remove spaces so schroot does not complain
+       
+       # setup the schroot directory
+       os.mkdir(chroot)
+       for folder in ["etc", "dev", "bin", "usr", "data"]:
+               os.mkdir(os.path.join(chroot, folder))
+       
+       # setup /etc/passwd and /etc/group
+       with open(os.path.join(chroot, "etc", "passwd"), "w") as f:
+               print >>f, "root:x:0:0:root:/root:/bin/bash"
+               print >>f, "{0}:x:{1}:{2}:,,,:/data:/bin/false".format(name, userpw.pw_uid, userpw.pw_gid)
+       with open(os.path.join(chroot, "etc", "group"), "w") as f:
+               print >>f, "root:x:0:"
+               usergrp = grp.getgrgid(userpw.pw_gid)
+               print >>f, "{0}:x:{1}:".format(usergrp.gr_name, usergrp.gr_gid)
+               if group:
+                       groupgrp = grp.getgrnam(group)
+                       assert usergrp.gr_gid != groupgrp.gr_gid
+                       print >>f, "{0}:x:{1}:{2}".format(groupgrp.gr_name, groupgrp.gr_gid, name)
+       
+       # user configuration
+       if userpw.pw_shell != schsh:
+               subprocess.check_output(["usermod", "--shell", schsh, name])
+       if group:
+               subprocess.check_output(["adduser", name, "schsh"])
+       
+       # done!
+
+if len(sys.argv) <= 1:
+       print "Usage: %s <usernames>" % sys.argv[0]
+else:
+       for name in sys.argv[1:]:
+               print "Setting up",name
+               setup(name)
diff --git a/schroot/user/copyfiles b/schroot/user/copyfiles
new file mode 100644 (file)
index 0000000..f888968
--- /dev/null
@@ -0,0 +1,4 @@
+# Files to copy into the chroot from the host system.
+#
+# <source and destination>
+/dev/null
diff --git a/schroot/user/nssdatabases b/schroot/user/nssdatabases
new file mode 100644 (file)
index 0000000..6f800d9
--- /dev/null
@@ -0,0 +1 @@
+# Do not copy anything.
diff --git a/schsh b/schsh
new file mode 100755 (executable)
index 0000000..270691e
--- /dev/null
+++ b/schsh
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+# Configuration
+shell = None # set to "/bin/bash" or similar to allow shell access
+allowCommands = ["scp", "rsync", "/usr/lib/openssh/sftp-server"]
+commandPaths = ["/usr/bin", "/bin"]
+
+# END of Configuration
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+# DO NOT TOUCH ANYTHING BELOW THIS LINE
+
+import logging, logging.handlers
+import os, sys, shlex, pwd
+
+logger = logging.getLogger("schsh")
+logger.setLevel(logging.INFO)
+logger.addHandler(logging.handlers.SysLogHandler(address = '/dev/log',
+                                               facility = logging.handlers.SysLogHandler.LOG_AUTH))
+
+def get_username():
+    return pwd.getpwuid(os.getuid()).pw_name
+
+def log(msg, lvl = logging.INFO):
+       logger.log(lvl, "%s[%d]: <%s> %s" % ("schsh", os.getpid(), get_username(), msg))
+
+def logquit(msg):
+       log(msg, logging.ERROR)
+       sys.exit(1)
+
+def addPath(prog):
+       if prog.startswith("/"):
+               return prog
+       # look for it in the paths
+       for path in commandPaths:
+               fullprog = os.path.join(path, prog)
+               if os.path.exists(fullprog):
+                       return fullprog
+       return None
+
+# parse arguments
+run = []
+if len(sys.argv) == 1:
+       if shell is None:
+               print "No shell for you!"
+               logquit("Shell access not allowed")
+       else:
+               run = [shell]
+elif len(sys.argv) == 3 and sys.argv[1] == "-c":
+       # check if the command is allowed, and add path
+       run = shlex.split(sys.argv[2])
+       if len(run) > 0 and run[0] in allowCommands:
+               run[0] = addPath(run[0])
+               log("Running '"+str(run)+"'")
+       else:
+               print "You are not allowed to run this command."
+               logquit("Attempt to run invalid command '"+sys.argv[2]+"'")
+else:
+       logquit("Invalid arguments for schsh: "+str(sys.argv))
+
+assert len(run) > 0
+os.execl("/usr/bin/schroot", "/usr/bin/schroot", "-c", "user-"+get_username(), "-d", "/data", "--", *run)
diff --git a/sshd_config b/sshd_config
new file mode 100644 (file)
index 0000000..7abe96a
--- /dev/null
@@ -0,0 +1,4 @@
+Match Group schsh
+        AllowTcpForwarding no
+        AllowAgentForwarding no
+        X11Forwarding no