Allow SFTP but disallow SSH?
Solution 1
Starting with version 4.9 OpenSSH (not available in centos 5.x but ChrootDirectory feature was backported) has an internal-sftp
subsystem:
Subsystem sftp internal-sftp
And then block other uses:
Match group sftponly
ChrootDirectory /upload/%u
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
ForceCommand internal-sftp
Add your users to the sftponly
group. The chroot directory must be owned by root, and cannot be group-writeable, so create a subdirectory for each user, e.g. uploads
or home/$username
that's owned by the appropriate user (if you match their home directory, it will be the default working directory when connecting). I'd also set /bin/false
as the user's shell.
As an example, users can then upload single files with:
sftp username@hostname <<< 'put filename.ext uploads/'
(scp will hopefully soon be modified to use sftp so this will become easier)
Solution 2
There is a shell scponly what does this. It can chroot too.
Solution 3
Checkout rssh which is a fake shell that allows sftp but denies ssh
More about RSSH
http://www.pizzashack.org/rssh/
RPMs
http://pkgs.repoforge.org/rssh/
You can configure rssh to allow / deny different behaviours like sft, scp etc.
Solution 4
I use the method of specifying the user shell as /bin/false as mentioned. However, you must ensure that /bin/shell is in /etc/shells. Then it works ssh=no ftp=ok.
I also use vsftpd and add this
chroot_local_user=YES
to
/etc/vsftpd/vsftpd.conf
so that ftp-ers can't see date other then their own.
Advantage to these simple changes are no annoying config to ssh config for each user.
Related videos on Youtube
Thomas Molloy
Updated on September 18, 2022Comments
-
Thomas Molloy over 1 year
The assignment is to search for a word inside a matrix (only left to right) by putting the word and starting point in the command line and return true if the word is there and false if it is not. Unfortunately, I continue to recieve a segmentation fault msg. Any help is greatly appreciated, thanks!
#include <iostream> #include <vector> #include <sstream> #include <string> using namespace std; int main(int argc, char *argv[]){ for(int i = 0; i < argc; i++){ cout << argv[i] << " "; } char word; argv[1] = &word; stringstream ss; string sWord; ss << word; ss >> sWord; int startRow = atoi(argv[2]); int startCol = atoi(argv[3]); int x, y; cin >> x >> y; cout << x << y << endl; vector < vector < char > > matrix; matrix.resize(x); for(int i = 0; i < matrix.size(); i++){ matrix.resize(y); for(int k = 0; k < matrix.size(); k++){ cin >> matrix[i][k]; } } for(int i = 0; i < strlen(argv[1]); i++){ if(matrix[startRow][startCol + i] != sWord[i]){ return false; } else{ return true; } } }
-
crashmstr over 8 yearsWhy are you assigning to
argv[1]
? -
alcedine over 8 yearsYou first instinct should be to use a debugger for things like this. Start by reading this, for example, or really just any one of these.
-
Thomas Molloy over 8 yearsargv[1] is the word im searching for that is put in the command line, how else can i do it?
-
crashmstr over 8 years
std::string sWord = argv[1];
(assumingargc
says there are enough parameters), but then usesWord
instead of C string functions likestrlen
later. -
Werner Henze over 8 yearsWhere does it crash and for what input does it crash?
-
Thomas Molloy over 8 yearsI get this error msg when i try to compile now with that change: no matching function for call to 'strlen' for(int i = 0; i < strlen(sWord); i++){
-
Thomas Molloy over 8 yearscandidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') to 'const char *' for 1st argument
-
Thomas Matthews over 8 yearsReplace
strlen
withword.size()
orword.length()
. -
underscore_d over 8 yearsYes, when coding C++, you should use C++ string types and functions. Mixing in C things is just going to cause confusion and possibly UB. Get used to C++'s standard library from the beginning, and if you're anything like me, you won't look back.
-
Thomas Molloy over 8 yearsstill getting a segmentation fault with these changes: std::string sWord = argv[1]; int wordLength = sWord.length();
-
-
Tommy B. over 12 yearsWow! Super-awesome! I'll test this out and come back here to validate. Thanks a lot!
-
splattne over 12 yearsDid you test this?
-
Kyle over 12 years+1 for the ChrootDirectory thing!
-
Dragos about 12 yearsThis would come great if you need both SFTP users and SSH users. You just replace the shell in /etc/passwd for those restricted only to SFTP.
-
Brad Mace about 11 yearsWhen I try setting the shell to
/bin/false
neither ssh or sftp works -
jwbensley almost 10 years/bin/false is to disallow any sort of login, that is not the correct approach here. The accepted answer from Rob Wouters' is how you should limit users to SFTP only, not by changing the shell. If you did want to change the shell @Stone's asnwer would be a good idea.
-
Emilio Nicolás over 9 yearsAfter doing this, my sftponly user cant access by ssh and is able to connect by sftp. However it can't see any file at all! In spite these files have permission for this user. :-(
-
Xosofox almost 9 yearsIn case you want to do this and find an entry in your sshd_config with "/usr/lib/openssh/sftp-server" already existing, check here: serverfault.com/questions/660160/… -- internal-sftp is "newer, better and easier"
-
Thomas Molloy over 8 yearsdont I have to assign argv[1] to char, and do you have any solutions to this problem in mind? Do i need to make an array of chars for word for every letter and then just use that array in the final for loop?
-
Thomas Matthews over 8 years@ThomasMolloy: Make your life easier. Switch to using
std::string
. Usestd::string::length()
to find the length of the string. You can also use some of the other methods likefind
andsubstr
. -
Thomas Molloy over 8 yearsstill getting a segmentation fault with these changes: std::string sWord = argv[1]; int wordLength = sWord.length();
-
Thomas Molloy over 8 yearsinstead of all this: char word; argv[1] = &word; stringstream ss; string sWord; ss << word; ss >> sWord;
-
Putnik over 6 yearsso WHAT shell should be used assuming /bin/bash is not acceptable and /bin/false or /sbin/nologin deny access?
-
Tomofumi over 5 yearsNice. This is the easiest way to config without touching sshd_config at all. Just change the shell in passwd file and done.
-
Victor Gavro about 4 yearsHome directory should not only be owned by root, but also has 755 permission (no write access), which makes this chroot additional receipt not usable in most cases.
-
user3132194 about 4 years
rssh
seems to be obsolete now (there is no this package in debian buster anymore), they say, there isrush
instead of it. I did not tried it, i am moving to openssh with internal-sftp. -
leonheess about 4 yearsHow can you set /bin/false as user shell for the group sftponly instead of each user individually?
-
mbbush over 3 yearsCommenting out lines that you don't understand is generally a bad idea. If you don't know what PAM is for, just leave it set however your distro has it set as a default.
-
copycat over 3 years@leonheess The shell is a user attribute, so you would need to do a batch:
sudo groupmems -lg sftponly | sudo xargs -n1 usermod -s /bin/false
-
Andre Leon Rangel about 3 yearsit would be great if you post it here instead of linking it. What if the page goes down?
-
corretge over 2 yearsIt's a good approach but the SourceForge package has not been updated since 2011
-
MrR over 2 yearsWhy? / why not? unclear
-
Fjor about 2 yearsThe github repository of
scponly
is here. -
Sam Sirry about 2 yearsthis shell is no longer shipped with modern Debian. ssh should be used instead (detailed in another answer).
-
Sam Sirry about 2 years@VictorGavro, in deed, but you can add a directory inside the user's (chrooted) home dir, and then the user can do whatever in there.