portforward only key based chroot ssh access without a shell for the user under 64 Bit 
Match user USER
PasswordAuthentication no
AllowTcpForwarding yes
X11Forwarding no
PermitTunnel no
GatewayPorts no
AllowAgentForwarding no
ChrootDirectory /home/USER

But if the client needs a login shell this failed.

Well you could tell the client to not use a login shell:

ssh -N -L2222:IP:22 USER@SERVER

putty: SSH / Protocol Option enable "Don't start a shell or command at all"

or use an own loginshell where the user only can press return to disconnect:

sudo useradd USER -d /home/USER -s /bin/bash
sudo mkdir /home/USER
sudo chown USER:USER /home/USER
sudo su USER
touch .hushlogin (is used to not display motd's)
mkdir .ssh
chmod 0700 .ssh
cd .ssh
ssh-keygen -t rsa -b 4096
mv id_rsa.pub authorized_keys
sudo passwd -d USER
sudo chown root:root /home/USER (for sshd chroot)
sudo cp own_loginshell /home/USER/

move /home/USER/.ssh/id_rsa out to your test account and test with "ssh -i id_rsa USER@IP"

I had some troubles with a chrooted environment:

/etc/passwd USER:x:ID:ID::/home/USER:/own_loginshell

.hushlogin is NOT working and motd with last login is shown!
pam.d/sshd is running all scripts in /etc/update-motd.d.

Solution move .hushlogin to /home/USER/home/USER

To hide motd and have no delays at login we could add an exception in pam.d/sshd for our user USER

session [default=2 success=ignore] pam_succeed_if.so quiet user != USER


session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate

/etc/passwd USER:x:ID:ID::/:/own_loginshell

.hushlogin is working but before sshd is doing a chroot it checks the key against
authorized_keys based on our homedir (is / for chroot) wee need to

add "AuthorizedKeysFile /home/USER/.ssh/authorized_keys" to sshd_config


For 64Bit there is something different to 32Bit and with my studies i compiled with

gcc -s -Os -nostdlib -ffreestanding own_loginshell.c -o own_loginshell

#> chroot /ROOTDIR ./own_loginshell
chroot: failed to run command ‘./own_loginshell’: No such file or directory


#> strace chroot /ROOTDIR ./own_loginshell

you only see

execve("./own_loginshell", ["./own_loginshell"], 0x7fff17d94fe8 /* 24 vars */) = -1 ENOENT (No such file or directory)

But with the help of "readelf -l own_loginshell" you see

[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

You have to copy /lib64/ld-linux-x86-64.so.2 to CHROOT/lib64/

Or compile with "-static"

simple program to print to stdout and read from stdin without libc for x86-64

taken from https://hero.handmade.network/forums/code-discussion/t/861-compiling_without_libc_on_linux

gcc -s -Os -nostdlib -ffreestanding -static own_loginshell.c -o own_loginshell

#include <stddef.h>
#include <syscall.h>

static void exit(int code)
__asm__ __volatile__(
: "a"(__NR_exit)
: "cc", "rcx", "r11", "memory");
__builtin_unreachable(); // syscall above never returns

// returns negative value for error (for example, if error is EINVAL, then -EINVAL is returned)
static int write(int fd, const void *buf, size_t size)
long result;
__asm__ __volatile__(
: "=a"(result)
: "0"(__NR_write), "D"(fd), "S"(buf), "d"(size)
: "cc", "rcx", "r11", "memory");
return result;

static int read(int fd, char *buf, size_t size)
long result;
__asm__ __volatile__(
: "=a"(result)
: "0"(__NR_read), "D"(fd), "S"(buf), "d"(size)
: "cc", "rcx", "r11", "memory");
return result;

void _start()
char text[] = "press enter to close connection";

// for this example let's ignore result of write
// but you should really handle it
// 1 is stdout file handle
write(1, text, sizeof(text) - 1);
read(0, text, 1);


[ view entry ] ( 1817 views )   |  print article

<Back | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Next> Last>>