10

How can I change the value of, let's say, PasswordAuthentication in /etc/ssh/sshd_config in commands?

As well, remove a # in front of the "key" I wish to value. These don't all have to be in one command. I setup quite a few servers, and remembering where everything is gets exhausting, so I want to get a series of commands I can copy paste and it does the work for me for future reference.

Sample values:

PermitRootLogin no
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
UseDNS no

4 Answers 4

13

Regular expressions and sed can help with things like this.

sed -re 's/^(PasswordAuthentication)([[:space:]]+)no/\1\2yes/' -i.`date -I` /etc/ssh/sshd_config

On my Debian system, this will toggle PasswordAuthentication no to PasswordAuthentication yes, regardless of the number of spaces between key and value.

It will replace the option in the file (in-place editing) while creating a backup of the original file, with a suffix named by the date (sshd_config.2014-05-28).

Switch places for yes and no to toggle the other way.

The expression for removing a leading # is something like this:

 sed -re 's/^(\#)(PasswordAuthentication)([[:space:]]+)(.*)/\2\3\4/' 

-and for inserting a leading #-sign:

 sed -re 's/^(PasswordAuthentication)([[:space:]]+)(.*)/#\1\2\3/' 

To toggle a line with an optional #-sign in front (Thanks Barlop):

sed -re 's/^(\#?)(PasswordAuthentication)([[:space:]]+)no/\2\3yes/' 

In all these expressions you can change PasswordAuthentication to any other option you want to change - probably even make it a key in a shell script, and make a "sshd option toggle tool".

Sed and regex is all fun and games, but I'm sure Valentin is right about configuration management is the way to go if you have lots of systems. Personally I just use etckeeper/bazaar on a couple of systems that very rarely change - it's not configuration management, but it gives me versioning, so I can get back a working config after I screwed up with regex and sed -i. :)

4
  • Can you modify your regex to include optional # sign when searching, but not in the replacement? I want to remove the # sign before the PasswordAuthentication, just incase it exists.
    – Nahydrin
    May 27, 2014 at 22:46
  • Hm. It's easy to search for an optional character at the start of a line 's/^(\#?)/foo/' but it's another thing to conditionally leave it out. I would have to study the manuals of sed and regex(7), which is beyond the scope of this. :) But you can combine the two expressions here - first remove the comment-sign for KEY, then toggle KEY to yes or no.
    – Kenned
    May 27, 2014 at 23:03
  • @Kenned You can by, in the search, capturing the part you want and the part you don't want, and in the replace, just including the part you want.
    – barlop
    May 29, 2014 at 1:59
  • In case one needs to toggle yes/no setting, one can do so by sed '/^PasswordAuthentication /{s/yes/no/;t;s/no/yes/}' -i /etc/ssh/sshd_config and use it as sed '/^PasswordAuthentication /{s/yes/no/;t;s/no/yes/}' -i /etc/ssh/sshd_config && grep '^PasswordAuthentication ' /etc/ssh/sshd_config && /etc/init.d/ssh reload for example.
    – PF4Public
    May 5, 2016 at 18:55
6

There is a number of options to choose from:

  • Puppet, Cfengine, Chef or any other configuration management tool
  • Augeas (augtool -> print /files/etc/ssh/sshd_config -> then use "set")
  • sed -i
  • and many more

After trying to guess where you want to go to, you probably want to consider using configuration management anyway.

2
  • Can you give me an example using sed?
    – Nahydrin
    May 27, 2014 at 22:22
  • +1 for giving 3 possible solutions. And, @BrianGraham err brian it's really not hard to find out how to do a search and replace with sed. sed -i 's/a/b/' a.a (replaces 'a' with 'b' in file 'a.a'. More complex with a regex but then your question is how to do the regex, rather than sed or ssh
    – barlop
    May 27, 2014 at 23:09
5

Augeas with its command line tool - augtool - can configure /etc/ssh/sshd_config. For example:

augtool --autosave 'set /files/etc/ssh/sshd_config/PasswordAuthentication yes'

To set all the values use:

SSHD_UsePAM=no
SSHD_UseDNS=no
augtool << EOF
set /files/etc/ssh/sshd_config/PermitRootLogin no
set /files/etc/ssh/sshd_config/ChallengeResponseAuthentication no
set /files/etc/ssh/sshd_config/PasswordAuthentication no
set /files/etc/ssh/sshd_config/UsePAM ${SSHD_UsePAM}
set /files/etc/ssh/sshd_config/UseDNS ${SSHD_UseDNS}
save
EOF
3
  • Just a note: that will not work if there's Match blocks in the file, as global parameters will need to be inserted before the first Match block.
    – raphink
    Jul 12, 2014 at 16:51
  • @ℝaphink, doesn't this apply to all other answers as well? Could you also pastebin a configuration file like that? Jul 12, 2014 at 17:07
  • That is true. I'll post an answer using Puppet + augeasproviders for that.
    – raphink
    Jul 14, 2014 at 16:28
1

sshd_config cannot be edited safely without being parsed entirely, because it can contain Match blocks.

Augeas is a good option to achieve that, but it's not very easy to manage inserting options in the right place when there are Match blocks already. One option is to use Puppet with the sshd_config Augeas-based provider:

sshd_config { "PermitRootLogin":
  ensure => present,
  value  => "yes",
}

This option gives you the advantage of using a strict parser (Augeas with the Sshd.lns lens) and an abstraction level (Puppet resource) which manages the complexity of setting parameters outside of Match blocks, but also inside of them:

sshd_config { "X11Forwarding":
  ensure    => present,
  condition => "Host foo User root",
  value     => "yes",
}
2
  • Could you please test if you can set the global PasswordAuthentication to no in this sshd_config? Jul 14, 2014 at 20:33
  • 1
    Yes I can confirm, just did it.
    – raphink
    Jul 17, 2014 at 20:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .