sftp/scp chroot solution?

neurosis

Member


Messages: 66

#1
I have been struggling with this for two days. I had this working easily in a previous version of FreeBSD using scponly. I am not sure but it appears to be broken now. I can scp to the sshd but not sftp. It errors with "Cannot initialize SFTP protocol. Is the host running a SFTP server?"

I have read several posts and threads regarding this problem but have not been able to come up with a solution. It appears that scponly now comes with a script that is to be run at start. I add it to my rc.conf and then try to run the script and this is what I get.

Code:
# /usr/local/etc/rc.d/scponlyc start
sftptest/dev
mount: dev : Operation not permitted
/usr/local/etc/rc.d/scponlyc: WARNING: devfs_domount(): Unable to mount devfs on /home/sftptest/dev
devfs rule: ioctl DEVFSIO_RGETNEXT: Operation not permitted
Since I am only a FreeBSD user and not a power user I have no idea why I am getting this error.

I also read that modern openssh includes a way to chroot users to their directory but I have not found any documentation explaining the process. I also see that it does it automatically if you have a /home/userdir/./ directory but I dont know how to create that.

Does anyone have any suggestions to help me get this working properly?

This is running inside of a jail btw but there are other things in the jail that I do not want the sftp/scp user to look at so I want them locked to their home dir.

this is FreeBSD 8.1-RELEASE
 

SirDice

Administrator
Staff member
Administrator
Moderator

Thanks: 6,332
Messages: 27,503

#2
Have a look at the scponlyc startup script. It most likely tries to mount a devfs in the chroot environment. You cannot mount any filesystems within a jail so the mounting has to occur on the host. You can use the jail_<jailname>_fstab for this.
 

vermaden

Son of Beastie

Thanks: 1,042
Messages: 2,694

#3
@neurosis

Like that mate:

Code:
/etc/group 
  chroot:*:999:

/etc/passwd 
  user:*:999:999:user:/data:/usr/sbin/nologin

/etc/ssh/sshd_config
  Match group          chroot
    ChrootDirectory    /home/%u
    X11Forwarding      no
    AllowTcpForwarding no
    ForceCommand       internal-sftp

# mkdir -p /home/user/data
# chown root:chroot /home/user
# chown user:chroot /home/user/data
 
OP
OP
N

neurosis

Member


Messages: 66

#4
@vermaden

I still get this error "Cannot initialize SFTP protocol. Is the host running a SFTP server?"

I created two users to test this out.. I create one called storage and set up as a normal user. I can scp/sftp to this no problem (it works!) but it is obviously not chroot.

So then I create a user (i hope) exactly as you said. I even called it "user". I cannot sftp or scp to this account. I used winscp to test and I dont get much of an error message to re-post.

I like the idea of chroot using your method if i can get it to work!


@sirdice

You are correct. The script creates a /dev directory in the userdir and then mounts devfs inside of the jail.

I dont understand how to use the <jails.fstab> to get this to work properly.. I dont know how to have it mount what it needs to I mean.

Here is the script.

Code:
# cat scponlyc
#!/bin/sh
#
# $FreeBSD: ports/shells/scponly/files/scponlyc.in,v 1.5 2010/03/27 00:14:50 dougb Exp $
#

# PROVIDE: scponlyc
# REQUIRE: LOGIN cleanvar
# KEYWORD: shutdown

# Add the following lines to /etc/rc.conf to enable scponly:
# scponlyc_enable (bool):               Set to "NO" by default.
#                                       Set it to "YES" to enable scponly
# scponlyc_shells (str):                Set to "/etc/shells" by default.
# scponlyc_passwd (str):                Set to "/etc/passwd" by default.

. /etc/rc.subr

scponlyc_shells="${scponlyc_shells:-/etc/shells}"
scponlyc_passwd="${scponlyc_passwd:-/etc/passwd}"

name="scponlyc"
rcvar=`set_rcvar`

start_cmd="scponlyc_startcmd"
stop_cmd="scponlyc_stopcmd"

required_files="$scponlyc_shells $scponlyc_passwd"

scponlyc=/usr/local/sbin/scponlyc

make_devfs() {
        # $1 is the user name whose home directory needs a minimal
        # devfs created. If ~/dev exists, it will be deleted.

        eval DEV="~$1/dev"
        if /sbin/mount | grep "${DEV}" >/dev/null 2>&1; then
                /sbin/umount "${DEV}" 2>/dev/null
        fi
        /bin/rmdir "${DEV}" || err 1 "Unable to remove $DEV"
        /bin/mkdir -p "${DEV}"
        devfs_domount "${DEV}"
        if devfs_init_rulesets; then
                devfs_apply_ruleset "devfsrules_hide_all" "${DEV}" && \
                devfs_apply_ruleset "devfsrules_unhide_basic" "${DEV}" || \
                /sbin/umount "${DEV}" 2>/dev/null
        fi
}

users_configured() {

        if [ `/usr/bin/grep -c "/scponlyc$" ${scponlyc_shells} 2>/dev/null` -ne 1 ]; then
                exit 1
        fi
}

scponlyc_startcmd() {

        users_configured

        /usr/bin/grep "^[^#]*:.*:.*:.*:.*:.*:${scponlyc}$" ${scponlyc_passwd} |
                /usr/bin/awk -F: {'print $1'} |
                while read USER; do
                        /bin/echo "${USER}/dev"
                        make_devfs "${USER}"
                done
}

scponlyc_stopcmd() {

        users_configured

        /usr/bin/grep "^[^#]*:.*:.*:.*:.*:.*:${scponlyc}$" ${scponlyc_passwd} |
                /usr/bin/awk -F: {'print $1'} |
                while read USER; do
                        /bin/echo "${USER}/dev"
                        eval DEV="~${USER}/dev"
                        /sbin/umount ${DEV} 2>/dev/null
                done
}

load_rc_config $name
run_rc_command "$1"
 

SirDice

Administrator
Staff member
Administrator
Moderator

Thanks: 6,332
Messages: 27,503

#5
Assuming your jail is called "myjail" in /etc/rc.conf. Just create a /etc/fstab.myjail (on the host!) with something like:
Code:
devfs    /jail/myjail/usr/home/chroot/directory/dev     devfs    rw    0   0
These filesystems will get mounted/unmounted when the jail is started/stopped.
 
OP
OP
N

neurosis

Member


Messages: 66

#6
SirDice said:
Assuming your jail is called "myjail" in /etc/rc.conf. Just create a /etc/fstab.myjail (on the host!) with something like:
Code:
devfs    /jail/myjail/usr/home/chroot/directory/dev     devfs    rw    0   0
These filesystems will get mounted/unmounted when the jail is started/stopped.
SirDice! you are the man! It works very good! There should be a howto on this. I have not been able to find any information on this unfortunately and it was so simple.


Vermaden,

I would still like to know your method if you have time to explain better. That seems like it would be a better option as it uses the base system.

Thanks guys.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Thanks: 6,332
Messages: 27,503

#7
neurosis said:
SirDice! you are the man! It works very good! There should be a howto on this. I have not been able to find any information on this unfortunately and it was so simple.
Have a look in /etc/defaults/rc.conf, there are more jail 'tricks'.

You can also add (if you need it)
Code:
jail_myjail_devfs_enable="YES"
That will mount a devfs on the jail's /dev/
 

vermaden

Son of Beastie

Thanks: 1,042
Messages: 2,694

#8
neurosis said:
@vermaden

I still get this error "Cannot initialize SFTP protocol. Is the host running a SFTP server?"

I created two users to test this out.. I create one called storage and set up as a normal user. I can scp/sftp to this no problem (it works!) but it is obviously not chroot.

So then I create a user (i hope) exactly as you said. I even called it "user". I cannot sftp or scp to this account. I used winscp to test and I dont get much of an error message to re-post.

I like the idea of chroot using your method if i can get it to work!
Here is how it looks connected:


... or by terminal:
Code:
% sftp user@host.com
Password:
Connected to host.com.
sftp> ls -l
drwxr-xr-x    2 999      999             2 Oct 28 05:25 data
sftp> pwd
Remote working directory: /
sftp> 
bye       cd        chdir     chgrp     chmod     chown     df        dir       exit      get       help      lcd       lchdir    lls       
lmkdir    ln        lpwd      ls        lumask    mkdir     progress  put       pwd       quit      rename    rm        rmdir     symlink   
version   !         ?         
sftp>
Have You restarted sshd(8) daemon after adding changes to its config file?
Have You set any password to the 'user' user?
 

rbelk

Active Member

Thanks: 54
Messages: 199

#9
Vermaden, I think the password entry wont work. Didn't you leave out a few entries? I think it should look like this?
Code:
xfuser:*:999:999::0:0:xfuser/data:/usr/sbin/nologin
I did try your setup. The xfuser does connect without errors to the sftp subsystem, but my system is expecting password authentication. I did not give xfuser a password. Does the user have to generate SSH keys for authentication? I did restart sshd.
 

vermaden

Son of Beastie

Thanks: 1,042
Messages: 2,694

#10
I forgot about /etc/master.passwd file (# vipw in terminal)
Code:
/etc/master.passwd
  user:*:999:999::0:0:user:/data:/usr/sbin/nologin

/etc/passwd 
  user:*:999:999:user:/data:/usr/sbin/nologin
Now make user 'user' a password by # passwd user command in terminal.
 
OP
OP
N

neurosis

Member


Messages: 66

#11
vermaden said:
Here is how it looks connected:

Have You restarted sshd(8) daemon after adding changes to its config file?
Have You set any password to the 'user' user?
yes.. i restarted sshd and even restarted the jail.

Let me post what i have done to make sure that I didnt miss anything.

sshd_conf
Code:
Match group          chroot
   ChrootDirectory    /home/%u
   X11Forwarding      no
   AllowTcpForwarding no
   ForceCommand       internal-sftp
group

Code:
chroot:*:999:
passwd
Code:
user:*:999:999:user:/data:/usr/sbin/nologin
master.passwd

Code:
user:thereisapasswordherenow:999:999::0:0:user:/data:/usr/sbin/nologin

directories
Code:
# ls -al
total 12
drwxr-xr-x  3 root  chroot  512 Nov 26 01:12 .
drwxr-xr-x  4 root  wheel   512 Nov 26 00:45 ..
drwxr-xr-x  2 user  chroot  512 Nov 26 00:56 data
I still cant connect via sftp. what did i miss?
 

vermaden

Son of Beastie

Thanks: 1,042
Messages: 2,694

#12
@neurosis

Dunno mate, here is my /etc/ssh/sshd_config file:

(at least these line are not commented)

Code:
Subsystem       sftp    /usr/libexec/sftp-server

Match group chroot
   ChrootDirectory /home/%u
   X11Forwarding no
   AllowTcpForwarding no
   ForceCommand internal-sftp
 
OP
OP
N

neurosis

Member


Messages: 66

#13
vermaden said:
@neurosis

Dunno mate, here is my /etc/ssh/sshd_config file:

(at least these line are not commented)

Code:
Subsystem       sftp    /usr/libexec/sftp-server
Yes... that line is not commented in my file too. sftp works if i create a normal user and do not try to chroot them in to their home directory. Im not sure what is going on. When I try to sftp in from a linux system it only tells me this.

Code:
$ sftp user@host.com
Connecting to host.com...
Password:
Received message too long 1416128883
Then it ends.. yesterday I tried from a freebsd system and I got some strange authentication error. This is hard to track down.. I searched on google and seems that this error could be tied in to nologin? I havent found a solution.
 
OP
OP
N

neurosis

Member


Messages: 66

#14
@vermaden

I dont know what is going on, but i follow your steps exactly and it gives me errors. It acts as if the user account does not exist.
Code:
# chown user:chroot /home/user/data/
chown: user: Invalid argument
Code:
# passwd user
passwd: user: no such user
I tried to set this up in the host system outside of the jail to see if the jail was causing an issue. I added the appropriate lines to the group, passwd, and master.passwd files.

Not being able to figure this out is really bringing me down.. <grin> It seems like it should be very simple. I wonder if I should start a new topic regarding this?
 
OP
OP
N

neurosis

Member


Messages: 66

#15
Ok! I got it to work. I changed the way that I created the user. Please explain to me why this works but I could not get it to work using your method. It does not make sense to me. Here are the steps that I took.

First I edited the sshd_config file to reflect the changes that you suggested and restarted sshd.

Code:
/etc/ssh/sshd_config

Match group chroot
   ChrootDirectory /home/%u
   X11Forwarding no
   AllowTcpForwarding no
   ForceCommand internal-sftp

#/etc/rc.d/sshd restart
I then edited the group file (I was going to use pw groupadd but decided to just edit to keep your 999 GID) and added

Code:
/etc/group
chroot:*:999:
I created the user as I would normally using adduser

Code:
# adduser
Username: user
Full name:
Uid (Leave empty for default):
Login group [user]: chroot
Login group is chroot. Invite user into other groups? []:
Login class [default]:
Shell (sh csh tcsh bash rbash scponly scponlyc nologin) [sh]: nologin
Home directory [/home/user]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username   : user
Password   : *****
Full Name  :
Uid        : 1002
Class      :
Groups     : chroot
Home       : /home/user
Home Mode  :
Shell      : /usr/sbin/nologin
Locked     : no
OK? (yes/no): yes
adduser: INFO: Successfully added (user) to the user database.
Add another user? (yes/no): no
Goodbye!
Once the user was created I went to your steps for modifying home directory ownership.

Code:
# mkdir -p /home/user/data
# chown root:chroot /home/user
# chown user:chroot /home/user/data
My passwd and master.passwd file looks a bit different.

Code:
#/etc/passwd
user:*:1002:999:User &:/home/user:/usr/sbin/nologin

#/etc/master.passwd
user:wittypasswordhere:1002:999::0:0:User &:/home/user:/usr/sbin/nologin

I then sftp in to the users account and it worked! the only difference is that it does not start in the /user/data directory. It logs in to the users home direcory. It is chroot in to that directory! I really like this method! There should be a howto in the howto section for this! I would make one myself but I would not be able to answer any questions.. :D

I am not sure why this method worked and I could not get yours to work! I wish you could explain it to me! I dont understand what the difference is.
 
OP
OP
N

neurosis

Member


Messages: 66

#17
kpa said:
Difference is that you edited /etc/passwd directly and didn't use pwd_mkdb(8) to update etc/master.passwd. adduser(8) updated /etc/master.passwd automatically.

But rbelk or Vermaden did not use pwd_mkdb and were able to get this working. I would like to know why they were able to get this to work that way and I was not.
 

rbelk

Active Member

Thanks: 54
Messages: 199

#18
neurosis said:
But rbelk or Vermaden did not use pwd_mkdb and were able to get this working. I would like to know why they were able to get this to work that way and I was not.
Neurosis, I edited the password file with vipw, it automatically runs pwd_mkdb. I also didn't get it to work either. After my trip home from Thanksgiving, I'll see what the problem is.
 

vermaden

Son of Beastie

Thanks: 1,042
Messages: 2,694

#19
neurosis said:
But rbelk or Vermaden did not use pwd_mkdb and were able to get this working. I would like to know why they were able to get this to work that way and I was not.
I user the adduser command, I just posted what should be in /etc/*passwd to make it work mate.
 
Top