How do I copy files that need root access with scp?
Solution 1
You're right, there is no sudo
when working with scp
. A workaround is to use scp
to upload files to a directory where your user has permissions to create files, then log in via ssh and use sudo
to move/copy files to their final destination.
scp -r folder/ [email protected]:/some/folder/you/dont/need/sudo
ssh [email protected]
$ sudo mv /some/folder /some/folder/requiring/perms
# YOU MAY NEED TO CHANGE THE OWNER like:
# sudo chown -R user:user folder
Another solution would be to change permissions/ownership of the directories you uploading the files to, so your non-privileged user is able to write to those directories.
Generally, working in the root
account should be an exception, not a rule - the way you phrasing your question makes me think maybe you're abusing it a bit, which in turn leads to problems with permissions - under normal circumstances you don't need super-admin privileges to access your own files.
Technically, you can configure Ubuntu to allow remote login directly as root
, but this feature is disabled for a reason, so I would strongly advice you against doing that.
Solution 2
Quick way
From server to local machine:
ssh user@server "sudo cat /etc/dir/file" > /home/user/file
From local machine to server:
cat /home/user/file | ssh user@server "sudo tee -a /etc/dir/file"
Solution 3
Another method is to copy using tar + ssh instead of scp:
tar -c -C ./my/local/dir \
| ssh [email protected] "sudo tar -x --no-same-owner -C /var/www"
Solution 4
You can also use ansible
to accomplish this.
Copy to remote host using ansible's copy
module:
ansible -i HOST, -b -m copy -a "src=SRC_FILEPATH dest=DEST_FILEPATH" all
Fetch from remote host using ansible's fetch
module:
ansible -i HOST, -b -m fetch -a "src=SRC_FILEPATH dest=DEST_FILEPATH flat=yes" all
NOTE:
- The comma in the
-i HOST,
syntax is not a typo. It is the way to use ansible without needing an inventory file. -
-b
causes the actions on the server to be done as root.-b
expands to--become
, and the default--become-user
is root, with the default--become-method
being sudo. -
flat=yes
copies just the file, doesn't copy whole remote path leading to the file - Using wildcards in the file paths isn't supported by these ansible modules.
- Copying a directory is supported by the
copy
module, but not by thefetch
module.
Specific Invocation for this Question
Here's an example that is specific and fully specified, assuming the directory on your local host containing the files to be distributed is sourcedir
, and that the remote target's hostname is hostname
:
cd sourcedir && \
ansible \
--inventory-file hostname, \
--become \
--become-method sudo \
--become-user root \
--module-name copy \
--args "src=. dest=/var/www/" \
all
With the concise invocation being:
cd sourcedir && \
ansible -i hostname, -b -m copy -a "src=. dest=/var/www/" all
P.S., I realize that saying "just install this fabulous tool" is kind of a tone-deaf answer. But I've found ansible to be super useful for administering remote servers, so installing it will surely bring you other benefits beyond deploying files.
Solution 5
May be the best way is to use rsync
(Cygwin/cwRsync in Windows) over SSH?
For example, to upload files with owner www-data
:
rsync -a --rsync-path="sudo -u www-data rsync" path_to_local_data/ [email protected]:/var/www
In your case, if you need root privileges, command will be like this:
rsync -a --rsync-path="sudo rsync" path_to_local_data/ [email protected]:/var/www
Related videos on Youtube
Dimitris Sapikas
I am student at TEI of Piraeus, IEEE SB of TEI Piraeus Chair and Firefox TEI of Piraeus Club Lead
Updated on September 18, 2022Comments
-
Dimitris Sapikas over 1 year
I have an Ubuntu server to which I am connecting using SSH.
I need to upload files from my machine into
/var/www/
on the server, the files in/var/www/
are owned byroot
.Using PuTTY, after I log in, I have to type
sudo su
and my password first in order to be able to modify files in/var/www/
.But when I am copying files using WinSCP , I can't create create/modify files in
/var/www/
, because the user I'm connecting with does not have permissions on files in/var/www/
and I can't saysudo su
as I do in case of an ssh session.Do you know how i could deal with this ?
If I was working on my local machine, I would call
gksudo nautilus
but in this case I only have terminal access to the machine.-
dobey over 11 yearsThis seems more like a question for your virtual server provider, or for the putty or winscp developers.
-
Dimitris Sapikas over 11 years@dobey you obviusly wrong , it is about ubuntu privileges !
-
Sergey over 11 yearsWhy is this closed? This is a perfectly valid question about copying files with scp - every web developer is familiar with this situation
-
h3. over 11 yearsCopying protected files between servers in one line? should help.
-
JanezKranjski about 6 yearsI have a similar problem. I create a file (HTML in this case) on Windows computer and try to copy it with WinSCP to /var/www/html/website folder. And it says that there is a permission problem. Because I can copy to my /home folder I copied the file in two steps, but it isn't very convenient :-) I tried with adding my user to www-data group, but it didn't help. Any idea why adding to user to www-data still don't allow user to copy a file to folder which is owned by www-data group?
-
-
Dimitris Sapikas over 11 yearsi didn't get the first solution , could you please be a litle more spesific ?
-
Dimitris Sapikas over 11 yearsWhe i say my own files i mean /var/www , i am using my vps as web server .... on my own folder i have full access
-
Dimitris Sapikas over 11 yearsi am using this solution any way , but what if i could get full access to my own file system , i don't want to type
sudo chow ...
for every single directory :S -
trognanders over 11 yearsChanging ownership of all system files to the user for passing convenience is highly discouraged. It allows any userspace bug you might encounter to severely compromise the security of your system. It is much better to change the ownership of the files that you need to change or update by SCP, but to leave everything else owned by root (like it is supposed to be). That said, the
-R
inchown
tells it to change the ownership of that directory, and all children files and directories recursively... so you can do anything you like. -
Dimitris Sapikas over 11 yearshmm .... that seems working fine , thank you ! sorry i can't upvote (system does not allow me to do ...)
-
Sergey over 11 yearsRe. the first solution. 1.
scp -R mysite [email protected]:/home/dimitris/
2.ssh [email protected]
3.sudo mv ~/mysite /var/www
- it's a 2-step process, first youscp
the files to your home dir, then you log in via ssh and copy/move the files to where they should be -
test30 over 10 years@Braiam yeah, sure, sorry for link, the script is pretty long and that was the reason :)
-
mttdbrd about 9 yearsThis is the best way to do it.
-
Michael Lindman almost 9 yearsWelcome to Ask Ubuntu. Could you please include the script in your answer? I know it is unlikely but if the github repo was ever removed or the url changed then the answer would be void. It is better to include the script directly and leave the github repo as a source.
-
typeduke over 8 yearsI can't get this method to work successfully. As written I get
sudo: sorry, you must have a tty to run sudo
. If I add "-t" to allocate a TTY then I getPseudo-terminal will not be allocated because stdin is not a terminal.
. I can't see this working without passwordless sudo. -
Mike D over 8 yearsI like the this answer but I recommend you direct it at the asked question versus more generalized commentary before upvote. something like
ansible -i "hostname," all -u user --become -m copy -a ...
-
erik.weathers about 8 years@MikeD: how do the above changes look?
-
Mike D about 8 yearsbetter but it's fails,
--module-name
is the correct switch name. and sincehostname
is the only host in your inventory, you can just sayall
-
erik.weathers about 8 yearsah, definitely a great point with
all
, I've updated all 3 cmds with that. And good catch with--module-name
instead of--module
. -
user3757405 almost 8 yearsWould something like
-i 'host,'
be valid syntax? I think it's easy to lose punctuation like that when reading a command. (For the reader I mean, if not the shell.) -
erik.weathers almost 8 yearshi @mwfearnley: I'm not sure I follow the question. The syntax is valid, in that it is the only way supported by ansible to directly specify the hostnames without using an inventory file. I agree that it's not obvious nor intuitive, but "it is what it is". ¯\_(ツ)_/¯
-
user3757405 almost 8 yearsI'm just wondering if the
host,
could be validly wrapped in quotes, just to show someone reading a script that: a) yes, there's supposed to be a comma there; and: b) don't worry, the extra punctuation won't, and can't, get misinterpreted by the shell. -
erik.weathers almost 8 years@mwfearnley: sure, the shell will treat
-i 'host,'
and same as-i host,
or-i "host,"
. In general I prefer to keep these invocations as short as possible to keep them from being daunting, but you should feel free to make it as verbose and explicit as you think is needed for clarity. -
typeduke over 7 years@AlexanderBird While that works in many cases, I'm not sure it works here because we're trying to pipe a tarball over the SSH connection. See serverfault.com/questions/14389/…
-
markgo2k about 6 yearsThis answer is underrated. It's simple, clean, reads or writes a root file with a single atomic operation, and requires nothing that's not already guaranteed to be there if you're using scp. Main drawback is that it does not copy permissions. If you want that, the tar solution is better. This is a powerful technique, particularly if combined with xargs/bash magic to traverse paths..
-
forumulator almost 6 yearsThis is what finally worked for me. You don't have permissions to a remote file that you want to copy to local, do a
sudo tar
, archive it, change permissions usingchmod
andchown
, and then copy it to local. Especially if it's a directory. -
jonatan over 5 yearsWay to go thinking outside the box! Great use of Ansible
-
przemo_li over 5 yearstar: Cowardly refusing to create an empty archive I think I'm selecting folders incorrectly is 'dir' the folder to be compressed? Is '/var/www/dir' the folder that will be created by uncompressing?
-
Korayem over 5 yearsI think the question was about uploading a file from local to remote and not vice versa
-
jaygooby over 5 yearsIf you're already in the directory you want to tar up, use
tar -c * | ssh [email protected] "sudo tar -x --no-same-owner -C /var/www"
-
Ed Neville about 5 yearsBuilding on the above, what I tend to do is: tar -cf - * | ssh [email protected] sudo /bin/bash -c '( cd /var/www && tar -xf - --no-same-owner )', this is typically because /bin/bash is listed in sudoers but tar might not be at $CORP, or sometimes it is su - that is listed. It can get uglier :)
-
Jeremy about 5 yearsBeautifully done. This is exactly what I was looking for both up and down. Thank you
-
Andrew Watson almost 5 yearsDeserves to be the top answer, for sure.
-
lucidbrot almost 5 yearsCan this be done for a directory instead of a file as well?
-
conny over 4 years...but you will need to pass
-t
to ssh, unless {a number of prerequisite assumptions}. Otherwise it will error withsudo: no tty present and no askpass program specified
. Andtee -a
? The question is about copying, not about appending and at the same time echoing back to stdout. -
Daniel Harding about 4 yearsIf using bash, you can use
read -s passwd
instead of usingstty -echo
andstty echo
. -
WinEunuuchs2Unix almost 4 yearsIt's ludicrous you can't setup a
root
account to usescp
forroot
owned files.sudo
simply does not work. Who owns my computer me or Canonical? It's just as bad as Android and Google from that respect. IMHO. I just want to copy files from/usr/local/bin
from one machine I OWN to another machine I OWN. -
Sergey almost 4 years@WinEunuuchs2Unix: indeed you can to set up your machines so you can SSH in as root, all it takes is a small change in a config. Once you do that you can scp files as root as much as you want.
-
rh16 almost 4 yearsI will add that another way around
sudo: no tty present and no askpass program specified
is to specify"sudo -S cat /etc/dir/file"
rather than just"sudo cat /etc/dir/file"
-
Elliptical view almost 4 years"there is no sudo when working with scp", this is actually not completely true. You can use sudo scp.. to gain access to local root files. You can therefore ssh into the source machine, use and use sudo scp from there to get root files to or from a remote machine.
-
Sergey almost 4 years@Ellipticalview:That's a clever idea but it won't work in many scenarios (the source files are on a local machine behind NAT, no SSH server on the source machine, the files on the source machine are owned by root too :) )
-
Mohamed over 3 yearsIf you got something like
"msg": "Missing sudo password"
you can specify sudo user by appending--extra-vars "ansible_become_pass=yourPasswor"
after-b
-
erik.weathers over 3 years@Mohamed : interesting workaround. My instinctual reaction is that you should be careful specifying your password in clear text like this. i.e., Ensure it's not getting written to your shell history & that you are not running on a shared server, since the parameter would be visible in the process table. Also make sure ansible isn't logging / storing this anywhere locally or on the remote server.
-
bitinerant over 3 yearsThe
sudo -S cat ...
trick is great, but be aware, it WILL DISPLAY YOUR PASSWORD on the screen. -
Ernesto Allely over 3 yearsAnother thing to have in mind is if the server has a display banner will be added to the file, as well as the message
Connection to xxx.xxx.xxx.xxx closed
. In order to avoid that happening you need to add-o LogLevel=QUIET
to the ssh command. The command would be thenssh -o LogLevel=QUIET -t user@server "sudo cat /etc/dir/file" > /home/user/file
. -
Md. Minhazul Haque about 3 yearsThis should be the best answer. I just added
-K
which asks for sudo password. -
FedericoCapaldo over 2 yearsany way to do this for entire folders?
-
German Garcia over 2 yearshow to do this for an entire directory:
ssh user@server "tar -cf - dir" | tar -x
-
MewX over 2 yearsThanks! This is the best way for copying big protected files!