Mention some of the big changes in 3.0.0.
[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. ssh) 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 for 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>A better method that works with ssh (and is very safe) is to setup an ssh
34 key (see the ssh-key manpage) and ensure that ssh-agent forwarding is turned
35 on in your ssh client config (e.g. "ForwardAgent&nbsp;yes").  You would put
36 the public version of your key onto the middle and target systems (in the
37 ~/.ssh/authorized_keys file), and the private key on your local system (which
38 I recommend you encrypt).  With this setup, a series of ssh connections that
39 starts from the system where your private key is available will auto-authorize
40 (after a pass-phrase prompt on the first system if your key is encrypted).
41 See also ssh-agent for a way to keep a public key unlocked in memory for an
42 extended time, and the keychain project for a way to manage a system-wide,
43 per-user ssh-agent.
44
45 <p>To test that you have things setup right, first test a series of
46 remote-shell connections outside of rsync.  A command such as the following
47 should work without issuing multiple prompts (use the appropriate remote-shell
48 and the substitute the real hostnames for "middle" and "target", of course):
49
50 <blockquote><pre>ssh middle ssh target uptime</pre></blockquote>
51
52 <p>If you get a password/passphrase prompt to get into the first ("middle")
53 system that's fine, but the extra hop needs to occur without any extra user
54 interaction.
55
56 <p>Once that's done, you can do an rsync copy like this:
57
58 <blockquote><pre>rsync -av -e "ssh middle ssh" target:/src/ /dest/</pre></blockquote>
59
60 <h4>Method 2 -- requires ssh and nc (netcat)</h4>
61
62 <p>Assuming you're using ssh as your remote shell, you can configure ssh to
63 use a proxy command to get to the remote host you're interested in reaching.
64 Doing this will allow the multi-hop connection to work with rsync, even if
65 both hosts prompt for a password -- this is because both ssh connections
66 originate from the localhost, and thus both instances of ssh have access to
67 the local tty to use for an out-of-band password prompt.
68
69 <p>Here is an example config for your ~/.ssh/config file (substitute "target",
70 "target_user", and "middle" as appropriate):
71
72 <blockquote><pre>Host target
73   ProxyCommand nohup ssh middle nc -w1 %h %p
74   User target_user
75 </pre></blockquote>
76
77 <p>This proxy setup uses "ssh" to login to the firewall system ("middle") and
78 uses "nc" (netcat) to connect to the target host ("target") using the default
79 port number.  The use of "nohup" silences a warning at the end of the run, and
80 the "-w1" option tells nc to shut down when the connection closes.
81
82 <p>With this done, you can run a normal-looking rsync command to "target" that
83 will run the proxy command to get through the firewall system:
84
85 <blockquote><pre>rsync -av /src/ target:/dest/</pre></blockquote>
86
87 <h4>Method 3 -- an alternate ssh method for those without nc (netcat)</h4>
88
89 <p>Assuming you're using ssh as your remote shell, you can configure ssh to
90 forward a local port through your middle system to the ssh port (22) on the
91 target system.  This method does not require the use of nc (it uses only
92 ssh to effect the extra hop), but otherwise it is similar to, but slightly
93 less convenient than, method 2.
94
95 <p>The first thing we need is an ssh configuration that will allow us to
96 connect to the forwarded port as if we were connecting to the target
97 system, and we need ssh to know what we're doing so that it doesn't
98 complain about the host keys being wrong.  We can do this by adding this
99 section to your ~/.ssh/config file (substitute "target" and "target_user"
100 as appropriate, but leave "localhost" unchanged):
101
102 <blockquote><pre>Host target
103   HostName localhost
104   Port 2222
105   HostKeyAlias target
106   User target_user
107 </pre></blockquote>
108
109 <p>Next, we need to enable the port forwarding:
110
111 <blockquote><pre>ssh -fN -l middle_user -L 2222:target:22 middle</pre></blockquote>
112
113 <p>What this does is cause a connection to port 2222 on the local system to
114 get tunneled to the middle system and then turn into a connection to the
115 target system's port 22.  The -N option tells ssh not to start a shell on
116 the remote system, which works with modern ssh versions (you can run a
117 sleep command if -N doesn't work).  The -f option tells ssh to put the
118 command in the background after any password/passphrase prompts.
119
120 <p>With this done, you could run a normal-looking rsync command to "target"
121 that would use a connection to port 2222 on localhost automatically:
122
123 <blockquote><pre>rsync -av target:/src/ /dest/</pre></blockquote>
124
125 <p><b>Note:</b> starting an ssh tunnel allows anyone on the source system
126 to connect to the localhost port 2222, not just you, but they'd still need
127 to be able to login to the target system using their own credentials.
128
129 <h4>Method 4 -- for using rsync in daemon-mode (requires nc)</h4>
130
131 <p>Install and configure an rsync daemon on the target and use ssh and nc
132 to send the socket data to the remote host.
133
134 <blockquote><pre>RSYNC_CONNECT_PROG='ssh -l middle_user middle nc %H 873' \
135     rsync daemonuser@target::module/src/ /dest/</pre></blockquote>
136
137 <p>(You can also export that variable into your environment if you want to
138 perform a series of daemon rsync commands through the same middle host.)
139
140 <p>This command takes advantage of the RSYNC_CONNECT_PROG environment
141 variable, which tells rsync to pipe its socket data to an external program
142 in place of making a direct socket connection.  The command specifed above
143 uses ssh to run the nc (netcat) command on the middle host, which forwards
144 all socket data to port 873 on the target host (%H).  The "%H" will be
145 substituted with the target host from the rsync command as long as you're
146 running rsync 3.0.0 or newer (you'll need to replace %H with the actual
147 target hostname for earlier rsync versions, which makes the hostname
148 specified in the rsync command superfluous).
149
150 <h4>Method 5 -- for using rsync in daemon-mode (for those without nc)</h4>
151
152 <p>Install and configure an rsync daemon on the target and use an ssh
153 tunnel to reach the rsync sever.  This is similar to method 3, but it
154 tunnels the daemon port for those that prefer to use an rsync daemon.
155
156 <p>(Note that this method also works to tunnel a socket connection
157 directly to a destination system if you use "localhost" as the target
158 hostname and your destination system's name as the middle hostname.)
159
160 <p>Installing the rsync daemon is beyond the scope of this document, but
161 see the rsyncd.conf manpage for more information.  Keep in mind that you
162 don't need to be root to run an rsync daemon as long as you don't use a
163 protected port.
164
165 <p>Once your rsync daemon is up and running, you build an ssh tunnel
166 through your middle system like this:
167
168 <blockquote><pre>ssh -fN -l middle_user -L 8873:target:873 middle</pre></blockquote>
169
170 <p>What this does is cause a connection to port 8873 on the local system to
171 turn into a connection from the middle system to the target system on port
172 873.  (Port 873 is the normal port for an rsync daemon.) The -N option
173 tells ssh not to start a shell on the remote system, which works with
174 modern ssh versions (you can run a sleep command if -N doesn't work).  The
175 -f option tells ssh to put the command in the background after any
176 password/passphrase prompts.
177
178 <p>Now when an rsync command is executed with a daemon-mode command-line
179 syntax to the local system, the conversation is directed to the target
180 system.  For example:
181
182 <blockquote><pre>rsync -av --port 8873 localhost::module/src/ dest/
183 rsync -av rsync://localhost:8873/module/src/ dest/</pre></blockquote>
184
185 <p><b>Note:</b> starting an ssh tunnel allows anyone on the source system
186 to connect to the localhost port 8873, not just you, so you may want to
187 enable username/password restrictions on your rsync daemon.
188
189 <!--#include virtual="footer.html" -->