Moved the firewall tunneling info out of the FAQ (though it is
[rsync-web.git] / firewall.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
2 <HTML>
3 <HEAD>
4 <TITLE>rsync firewall tunneling</TITLE>
5 </HEAD>
6 <!--#include virtual="header.html" -->
7
8 <H2 align="center">Using rsync through a firewall</H2>
9
10 <p>If you have a setup where there is no way to directly connect two
11 systems for an rsync transfer, there are several ways to get a firewall
12 system to act as an intermediary in the transfer.
13
14 <p>This first method should work for any remote-shell (e.g. ssh, rsh, etc).
15 The other methods are all targeted at ssh (which has a lot of flexibility
16 in making a tunneled connection possible).
17
18 <h4>Method 1 -- should work with any remote-shell</h4>
19
20 <p>Use your remote shell (e.g. rsh) to access the middle system and have it
21 use a remote shell to hop over to the actual target system.
22
23 <p>To effect this extra hop, you'll need to make sure that the remote-shell
24 connection from the middle system to the target system does not involve any
25 tty-based user interaction (such as prompting for a password) because there
26 is no way for the middle system to access the local user's tty.
27
28 <p>One way that should work all remote-shell programs is to enable host-based
29 authentication, which would allow all connections from the middle system to
30 the target system to succeed (when the username remains the same).
31 However, this may not be a desirable setup.
32
33 <p>Another method that works with ssh (and is also very safe) is to setup
34 an ssh key (see the ssh-key manpage) and ensure that ssh-agent forwarding
35 is turned on (e.g. "ForwardAgent&nbsp;yes").  You would put the public
36 version of your key onto the middle and target systems, and the private key
37 on your local system (which I recommend you encrypt).  With this setup, a
38 series of ssh connections that starts from the system where your private
39 key is available will auto-authorize (after a pass-phrase prompt on the
40 first system if your key is encrypted).
41
42 <p>You should then test that a series of remote-shell connections works
43 without multiple prompts by running a command like this (substitute your
44 actual remote-shell and the hostnames "middle" and "target", of course):
45
46 <blockquote><pre>rsh middle rsh target uptime</pre></blockquote>
47
48 <p>If you get a password/passphrase prompt to get into the middle system
49 that's fine, but the extra hop needs to occur without any extra user
50 interaction.
51
52 <p>Once that's done, you can do an rsync copy like this:
53
54 <blockquote><pre>rsync -av -e "rsh middle rsh" target:/source/ /dest/</pre></blockquote>
55
56 <h4>Method 2 -- recommended method for ssh users</h4>
57
58 <p>Assuming you're using ssh as your remote shell, you can configure ssh to
59 use a proxy command to get to the remote host you're interested in reaching.
60 Doing this will allow the multi-hop connection to work with rsync, even if
61 both hosts prompt for a password -- this is because both ssh connections
62 originate from the localhost, and thus both instances of ssh have access to
63 the local console to use for an out-of-band password prompt.
64
65 <p>Here is an example config for your ~/.ssh/config file (substitute "target",
66 "target_user", and "middle" as appropriate):
67
68 <blockquote><pre>Host target
69   ProxyCommand nohup ssh middle nc -w1 %h %p
70   User target_user
71 </pre></blockquote>
72
73 <p>This proxy setup uses ssh to login to the firewall system ("middle") and
74 uses nc (netcat) to connect to the target host ("target") using the default
75 port number.  The use of "nohup" silences a warning at the end of the run,
76 and the "-w1" option tells nc to shut down when the connection closes.
77
78 <p>With this done, you could run a normal-looking rsync command to "target"
79 that would run the proxy command to get through the firewall system:
80
81 <blockquote><pre>rsync -av /src/ target:/dest/</pre></blockquote>
82
83 <h4>Method 3 -- an alternate ssh method for those without "nc"</h4>
84
85 <p>Assuming you're using ssh as your remote shell, you can configure ssh to
86 forward a local port through your middle system to the ssh port (22) on the
87 target system.  This method does not require the use of "nc" (it uses only
88 ssh to effect the extra hop), but otherwise it is similar to, but slightly
89 less convenient than, method 2.
90
91 <p>The first thing we need is an ssh configuration that will allow us to
92 connect to the forwarded port as if we were connecting to the target
93 system, and we need ssh to know what we're doing so that it doesn't
94 complain about the host keys being wrong.  We can do this by adding this
95 section to your ~/.ssh/config file (substitute "target" and "target_user"
96 as appropriate, but leave "localhost" unchanged):
97
98 <blockquote><pre>Host target
99   HostName localhost
100   Port 2222
101   HostKeyAlias target
102   User target_user
103 </pre></blockquote>
104
105 <p>Next, we need to enable the port forwarding:
106
107 <blockquote><pre>ssh -fN -l middle_user -L 2222:target:22 middle</pre></blockquote>
108
109 <p>What this does is cause a connection to port 2222 on the local system to
110 get tunneled to the middle system and then turn into a connection to the
111 target system's port 22.  The -N option tells ssh not to start a shell on
112 the remote system, which works with modern ssh versions (you can run a
113 sleep command if -N doesn't work).  The -f option tells ssh to put the
114 command in the background after any password/passphrase prompts.
115
116 <p>With this done, you could run a normal-looking rsync command to "target"
117 that would use a connection to port 2222 on localhost automatically:
118
119 <blockquote><pre>rsync -av target:/src/ /dest/</pre></blockquote>
120
121 <p><b>Note:</b> starting an ssh tunnel allows anyone on the source system
122 to connect to the localhost port 2222, not just you, but they'd still need
123 to be able to login to the target system using their own credentials.
124
125 <h4>Method 4 -- for using rsync in daemon-mode</h4>
126
127 <p>Install and configure an rsync daemon on the target and use an ssh
128 tunnel to reach the rsync sever.  This is similar to method 3, but it
129 tunnels the daemon port for those that prefer to use an rsync daemon.
130
131 <p>Installing the rsync daemon is beyond the scope of this document, but
132 see the rsyncd.conf manpage for more information.  Keep in mind that you
133 don't need to be root to run an rsync daemon as long as you don't use a
134 protected port.
135
136 <p>Once your rsync daemon is up and running, you build an ssh tunnel
137 through your middle system like this:
138
139 <blockquote><pre>ssh -fN -l middle_user -L 8873:target:873 middle</pre></blockquote>
140
141 <p>What this does is cause a connection to port 8873 on the local system to
142 turn into a connection from the middle system to the target system on port
143 873.  (Port 873 is the normal port for an rsync daemon.) The -N option
144 tells ssh not to start a shell on the remote system, which works with
145 modern ssh versions (you can run a sleep command if -N doesn't work).  The
146 -f option tells ssh to put the command in the background after any
147 password/passphrase prompts.
148
149 <p>Now when an rsync command is executed with a daemon-mode command-line
150 syntax to the local system, the conversation is directed to the target
151 system.  For example:
152
153 <blockquote><pre>rsync -av --port 8873 localhost::module/source dest/
154 rsync -av rsync://localhost:8873/module/source dest/</pre></blockquote>
155
156 <p><b>Note:</b> starting an ssh tunnel allows anyone on the source system
157 to connect to the localhost port 8873, not just you, so you may want to
158 enable username/password restrictions on your rsync daemon.
159
160 <!--#include virtual="footer.html" -->