Allow SFTP but disallow SSH?

67

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.

Share:
67

Related videos on Youtube

Thomas Molloy
Author by

Thomas Molloy

Updated on September 18, 2022

Comments

  • Thomas Molloy
    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
      crashmstr over 8 years
      Why are you assigning to argv[1]?
    • alcedine
      alcedine over 8 years
      You 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
      Thomas Molloy over 8 years
      argv[1] is the word im searching for that is put in the command line, how else can i do it?
    • crashmstr
      crashmstr over 8 years
      std::string sWord = argv[1]; (assuming argc says there are enough parameters), but then use sWord instead of C string functions like strlen later.
    • Werner Henze
      Werner Henze over 8 years
      Where does it crash and for what input does it crash?
    • Thomas Molloy
      Thomas Molloy over 8 years
      I 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
      Thomas Molloy over 8 years
      candidate 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
      Thomas Matthews over 8 years
      Replace strlen with word.size() or word.length().
    • underscore_d
      underscore_d over 8 years
      Yes, 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
      Thomas Molloy over 8 years
      still getting a segmentation fault with these changes: std::string sWord = argv[1]; int wordLength = sWord.length();
  • Tommy B.
    Tommy B. over 12 years
    Wow! Super-awesome! I'll test this out and come back here to validate. Thanks a lot!
  • splattne
    splattne over 12 years
    Did you test this?
  • Kyle
    Kyle over 12 years
    +1 for the ChrootDirectory thing!
  • Dragos
    Dragos about 12 years
    This 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
    Brad Mace about 11 years
    When I try setting the shell to /bin/false neither ssh or sftp works
  • jwbensley
    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
    Emilio Nicolás over 9 years
    After 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
    Xosofox almost 9 years
    In 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
    Thomas Molloy over 8 years
    dont 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
    Thomas Matthews over 8 years
    @ThomasMolloy: Make your life easier. Switch to using std::string. Use std::string::length() to find the length of the string. You can also use some of the other methods like find and substr.
  • Thomas Molloy
    Thomas Molloy over 8 years
    still getting a segmentation fault with these changes: std::string sWord = argv[1]; int wordLength = sWord.length();
  • Thomas Molloy
    Thomas Molloy over 8 years
    instead of all this: char word; argv[1] = &word; stringstream ss; string sWord; ss << word; ss >> sWord;
  • Putnik
    Putnik over 6 years
    so WHAT shell should be used assuming /bin/bash is not acceptable and /bin/false or /sbin/nologin deny access?
  • Tomofumi
    Tomofumi over 5 years
    Nice. This is the easiest way to config without touching sshd_config at all. Just change the shell in passwd file and done.
  • Victor Gavro
    Victor Gavro about 4 years
    Home 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
    user3132194 about 4 years
    rssh seems to be obsolete now (there is no this package in debian buster anymore), they say, there is rush instead of it. I did not tried it, i am moving to openssh with internal-sftp.
  • leonheess
    leonheess about 4 years
    How can you set /bin/false as user shell for the group sftponly instead of each user individually?
  • mbbush
    mbbush over 3 years
    Commenting 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
    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
    Andre Leon Rangel about 3 years
    it would be great if you post it here instead of linking it. What if the page goes down?
  • corretge
    corretge over 2 years
    It's a good approach but the SourceForge package has not been updated since 2011
  • MrR
    MrR over 2 years
    Why? / why not? unclear
  • Fjor
    Fjor about 2 years
    The github repository of scponly is here.
  • Sam Sirry
    Sam Sirry about 2 years
    this shell is no longer shipped with modern Debian. ssh should be used instead (detailed in another answer).
  • Sam Sirry
    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.