Scenario. The alice user logs in to the msk-web-01 server (centos7.2, selinux is enabled) using his ssh key and wants to launch the git pull command in the folder /www/mysite.ru/htdocs/ (owner of the folder - apache user).

To do this, write a small batch file:

#!/bin/sh #see http://ru.stackoverflow.com/questions/548545/ for details sudo setfacl -m apache:x $(dirname "$SSH_AUTH_SOCK") sudo setfacl -m apache:rwx "$SSH_AUTH_SOCK" cd /www/mysite.ru/htdocs/ pwd sudo su -s /bin/sh apache -c "/usr/bin/git pull" .... 

And it works ... giving out numerous warnings:

 /www/site1.ru/htdocs Could not create directory '/usr/share/httpd/.ssh'. Failed to add the ECDSA host key for IP address '1.2.3.4' to the list of known hosts (/usr/share/httpd/.ssh/known_ho). Already up-to-date. /www/site2.ru/htdocs Could not create directory '/usr/share/httpd/.ssh'. Failed to add the ECDSA host key for IP address '1.2.3.4' to the list of known hosts (/usr/share/httpd/.ssh/known_ho). Already up-to-date. 

The task is to get rid of these unnecessary records, achieving a clear conclusion by adding records to the global known_hosts.

You can get the desired effect by creating /usr/share/httpd/.ssh/known_hosts with the line CheckHostIP no :

 /www/site1.ru/htdocs Already up-to-date. /www/site2.ru/htdocs Already up-to-date. /www/site3.ru/htdocs Already up-to-date. 

Of course, this method is not considered as a solution to the problem, as well as other workarounds such as "completely disable the check" (say, once or twice )

PS Keys saved in one of two ways, first:

 ssh-keyscan -t rsa,dsa git.mycomany.ru >> /etc/ssh/ssh_known_hosts 

second:

 ssh-keyscan git.mycomany.ru >> /etc/ssh/ssh_known_hosts 

The difference is not particularly great: in the first case, Failed to add the RSA host, in the second case - Failed to add the ECDSA host key.

And even so with grief:

 ssh-keyscan git.mycomany.ru,1.2.3.4 >> /etc/ssh/ssh_known_hosts 
  • /usr/share/httpd is the user's home directory? ( $ grep /usr/share/httpd /etc/passwd ) - aleksandr barakin
  • @alexanderbarakin is the apache user directory in centos. The .ssh directory is not there, because user without shell. - AK
  • serverfault.com/q/107187/292034 - this is so that it does not require manipulation with acl-s. - aleksandr barakin
  • You refer to the topic, which I repeatedly re-read and worked out different aspects. Everything is correctly written there, but acl manipulations will inevitably be needed: pageant sends the key to a random folder every time, so you don’t have to set the right one time and another (you don’t want to give permanent access to the entire / tmp folder to users). - AK

2 answers 2

  1. As it turned out in the comments, /usr/share/httpd is the home directory of the apache user. it is this user that should own the directory (and all of its contents) /usr/share/httpd/.ssh :

     $ sudo chown -R apache /usr/share/httpd/.ssh 

    it should also be available only to the user himself:

     $ sudo chmod -R go= /usr/share/httpd/.ssh 
  2. You can add public keys (by default - the rsa , ecdsa and ed25519 types - see $ man ssh-keyscan ) of the git.mycompany.ru machine to the “known hosts” file of the apache user ( /usr/share/httpd/.ssh/known_hosts ) So:

     $ ssh-keyscan git.mycompany.ru | sudo tee -a /usr/share/httpd/.ssh/known_hosts 

    if this file did not exist before, the commands from the first item should be repeated after this operation.

  3. instead of manipulating acl (s) ( setfacl ... ) it’s better to add a line

     Defaults env_keep+=SSH_AUTH_SOCK 

    in /etc/sudoers (or even better - into a file with an arbitrary name that does not contain dots and tildes in the name, in the /etc/sudoers.d directory). for more details see, for example, here . It is better to edit these files through the visudo “wrapper” - see, for example, here .

clarification due to the requirement not to use the apache user's ~/.ssh .

  1. not to use ~/.ssh/config , but to be able to specify a specific configuration for a specific user, you can use the match user directive in /etc/ssh/ssh_config , adding to the end (this is important - see $ man ssh_config for the match option) This file is similar to the following:

     match user apache # какие-либо персональные настройки для пользователя apache 
  2. so that the ssh process does not use ~/.ssh/knonw_hosts , you can (by the method described in the previous paragraph) redefine for this user the value of the userknownhostsfile configuration variable, specifying, for example, the file /etc/ssh/ssh_known_hosts (or any other user accessible to read):

     userknownhostsfile /etc/ssh/ssh_known_hosts 

    The necessary keys in this file, of course, should already be added in advance. for example, in the manner described in the second paragraph of the first part of the answer.

  3. perhaps, by default, users need to hash the entries in known_hosts , then the ssh process will try to overwrite the key file. so that he does not do this, specify (at least for this user) not to hash the records by adding (as described in the first paragraph) the line:

     hashknownhosts no 
  • Alexander, thank you for your willingness to help, but your answer is absolutely completely in the wrong direction: the maintainers consistently remove the rights to the service records from which the demons run - and you offer to return them again (return the .ssh directory). In general, once I had it, web services started from under full-fledged accounts with the shell. But my liver quarterly pecked bezopasniki and after going to a dozen audits, I can already throw off some solutions with a large number of attack vectors. And I have already tried this solution and wrote in the question that it obviously does not fit. - AK
  • The ideal solution is to use the system-wide ssh_known_hosts file in which I will write the correct key. You will not need to create the .ssh directory in / usr / share / httpd / at all - all keys to the server are delivered ansible when the infrastructure changes. - AK
  • @AK, it is not clear how these your "bezopasniki" do not notice the presence of git-storage at the root of the sites and generally launching any processes on behalf of a non-shell user. // disable host-key verification is not necessary. so that ssh does not try to add a key, it should already be in the known_hosts file, respectively, you just need to specify ssh to use the global /etc/ssh/ssh_known_hosts file as userknownhostsfile , well, or any other readable file to which the necessary keys have already been added. - aleksandr barakin
  • @AK, this per-user configuration can be done without using ~/.ssh/config , directly in /etc/ssh/ssh_config using the match user directive. - aleksandr barakin
  • @AK, updated the response, transferring a substantial comment. - aleksandr barakin

In the end, everything was quite simple.

First, once again about the formulation of the problem. There are a number of trusted servers of the organization between which employees need to move while retaining authorization (ForwardAgent), so you need to be able to fill the /etc/ssh/ssh_known_hosts trusted data.

Firstly, git relies on system utilities in its communication with remote repositories via ssh, there are no special settings for ssh connection - you can read about hacks by creating an ssh file and exporting the variable GIT_SSH. Therefore, initially the question was more about ssh than specifically git.

Secondly, when I started to deal with keys (rsa, dsa, esdca) and protocol versions - I decided not only to disengage from git, but also from ansible, so that it would not affect, just in case.

After the tests, it turned out that the keys were generated correctly, the ssh settings (both default centros and my custom ones) also do not affect the operation.

All you need to do is print your fingerprints and write them to the general known_hosts:

 ssh-keyscan -t rsa,dsa git.mycomany.ru >> /etc/ssh/ssh_known_hosts 

Turning on hashing does not affect the result, either. And what is the effect?

Oddly enough - it turned out that influences ansible. If there is no file / etc / ssh / ssh_known_hosts on the disk - it creates a file with the rights rw-r - r-- but once it is restarted it is necessary again - the rights miraculously become rw ------- Of course, processes that want to read the repository and check whether there is such a print break off and find nothing. It is necessary only to restore the rights to the file - and the work is restored again.

An example of key filling is almost the same as in the documentation :

 - name: global pubkes for servers known_hosts: path='/etc/ssh/ssh_known_hosts' name='{{ item }}' key="{{ lookup('file', 'files/pubkeys/{{ item }}.pub') }}" with_items: - git.mycompany.ru 

I wanted to create a bug on the githaba - but before the institution I looked for whether it was ready. And found, here: https://github.com/ansible/ansible-modules-extras/issues/2513