diff --git a/bin/swift-auth-create-account b/bin/swift-auth-create-account index ccaf93cf5f..cdc085d754 100755 --- a/bin/swift-auth-create-account +++ b/bin/swift-auth-create-account @@ -36,8 +36,10 @@ if __name__ == '__main__': conf = dict(c.items('auth-server')) host = conf.get('bind_ip', '127.0.0.1') port = int(conf.get('bind_port', 11000)) + ssl = conf.get('cert_file') is not None path = '/account/%s/%s' % (new_account, new_user) - conn = http_connect(host, port, 'PUT', path, {'x-auth-key':new_password}) + conn = http_connect(host, port, 'PUT', path, {'x-auth-key':new_password}, + ssl=ssl) resp = conn.getresponse() if resp.status == 204: print resp.getheader('x-storage-url') diff --git a/bin/swift-auth-recreate-accounts b/bin/swift-auth-recreate-accounts index 51212b4f4f..3bdd1e43ee 100755 --- a/bin/swift-auth-recreate-accounts +++ b/bin/swift-auth-recreate-accounts @@ -31,8 +31,9 @@ if __name__ == '__main__': conf = dict(c.items('auth-server')) host = conf.get('bind_ip', '127.0.0.1') port = int(conf.get('bind_port', 11000)) + ssl = conf.get('cert_file') is not None path = '/recreate_accounts' - conn = http_connect(host, port, 'POST', path) + conn = http_connect(host, port, 'POST', path, ssl=ssl) resp = conn.getresponse() if resp.status == 200: print resp.read() diff --git a/doc/source/howto_cyberduck.rst b/doc/source/howto_cyberduck.rst new file mode 100644 index 0000000000..135272d9b4 --- /dev/null +++ b/doc/source/howto_cyberduck.rst @@ -0,0 +1,141 @@ +=============================== +Talking to Swift with Cyberduck +=============================== + +.. note:: + Put together by Caleb Tennis, thanks Celeb! + + +#. Install Swift, or have credentials for an existing Swift installation. If + you plan to install Swift on your own server, follow the general guidelines + in the section following this one. + +#. Verify you can connect using the standard Swift Tool `st` from your + "public" URL (yes I know this resolves privately inside EC2):: + + ubuntu@domU-12-31-39-03-CD-06:/home/swift/swift/bin$ st -A https://ec2-184-72-156-130.compute-1.amazonaws.com:11000/v1.0 -U a3:b3 -K c3 stat + Account: 06228ccf-6d0a-4395-889e-e971e8de8781 + Containers: 0 + Objects: 0 + Bytes: 0 + + .. note:: + + The Swift Tool `st` can be copied from Swift sources to most any + machine with Python installed. You can grab it from + http://bazaar.launchpad.net/%7Ehudson-openstack/swift/trunk/annotate/head%3A/bin/st + if you don't have the Swift code handy. + +#. Download and extract the Cyberduck sources (3.5.1 as of this writing). They + should be available at http://trac.cyberduck.ch/ + +#. Edit the Cyberduck source. Look for lib/cloudfiles.properties, and edit + this file. Change auth_url to your public auth URL (note the https):: + + auth_url=https://ec2-184-72-156-130.compute-1.amazonaws.com:11000/v1.0 + +#. Edit source/ch/cyberduck/core/Protocol.java. Look for the line saying + "storage.clouddrive.com". Just above that, change:: + + public boolean isHostnameConfigurable() { + return true; + } + +#. In the root directory, run "make" to rebuild Cyberduck. When done, type: + `open build/Release/Cyberduck.app/` to start the program. + +#. Go to "Open Connection", select Rackspace Cloud Files, and connect. + + .. image:: howto_cyberduck_config.png + +#. If you get SSL errors, make sure your auth and proxy server are both setup + for SSL. If you get certificate errors (specifically, 'unable to find valid + certification path to requested target'), you are using a self signed + certificate, you need to perform a few more steps: + + .. note:: + + For some folks, just telling the OS to trust the cert works fine, for + others use the following steps. + +#. As outlined here: http://blogs.sun.com/andreas/entry/no_more_unable_to_find, + download http://blogs.sun.com/andreas/resource/InstallCert.java, run "javac + InstallCert.java" to compile it, then run "java InstallCert + https://your-auth-server-url:8080". This script will pull down that + certificate and put it into a Java cert store, in your local directory. The + file is jssecacerts. + +#. You need to move that file to $JAVA_HOME/jre/lib/security, so your java run + time picks it up. + +#. Restart Cyberduck, and it should now allow you to use that certificate + without an error. + + +--------------------------------------- +Installing Swift For Use With Cyberduck +--------------------------------------- + +#. Both the proxy and auth servers will ultimately need to be running with + SSL. You will need a key and certificate to do this, self signed is ok (but + a little more work getting Cyberduck to accept it). Put these in + /etc/swift/cert.crt and /etc/swift/cert.key. + + .. note:: + + Creating a self-signed cert can usually be done with:: + + cd /etc/swift + openssl req -new -x509 -nodes -out cert.crt -keyout cert.key + +#. Example proxy-server config:: + + [proxy-server] + bind_port = 8080 + user = swift + cert_file = /etc/swift/cert.crt + key_file = /etc/swift/cert.key + + [auth-server] + ssl = true + +#. Example auth-server config:: + + [auth-server] + default_cluster_url = https://ec2-184-72-156-130.compute-1.amazonaws.com:8080/v1 + user = swift + cert_file = /etc/swift/cert.crt + key_file = /etc/swift/cert.key + +#. Use swift-auth-create-account to create a new account:: + + ubuntu@domU-12-31-39-03-CD-06:/home/swift/swift/bin$ swift-auth-create-account a3 b3 c3 + https://ec2-184-72-156-130.compute-1.amazonaws.com:8080/v1/06228ccf-6d0a-4395-889e-e971e8de8781 + + .. note:: + It's important that the URL that is given back to you be accessible + publicly. This URL is tied to this account, and will be served + back to Cyberduck after authorization. If this URL gives back + something like: http://127.0.0.1/v1/... this won't work, because + Cyberduck will attempt to connect to 127.0.0.1. + + This URL is specified in the auth-server config's + default_cluster_url. However, once you have created an + account/user, this URL is fixed and won't change even if you change + that configuration item. You will have to use sqlite to manually + edit the auth.db in order to change it (limitation of using the + development auth server, but perhaps someone will patch in this + ability someday). + +#. Verify you can connect using the standard Swift Tool `st`:: + + ubuntu@domU-12-31-39-03-CD-06:/home/swift/swift/bin$ st -A https://127.0.0.1:11000/v1.0 -U a3:b3 -K c3 stat + Account: 06228ccf-6d0a-4395-889e-e971e8de8781 + Containers: 0 + Objects: 0 + Bytes: 0 + +.. note:: + + Please let me know if you find any changes that need to be made: ctennis on + IRC diff --git a/doc/source/howto_cyberduck_config.png b/doc/source/howto_cyberduck_config.png new file mode 100644 index 0000000000..1612bbe0e6 Binary files /dev/null and b/doc/source/howto_cyberduck_config.png differ diff --git a/doc/source/index.rst b/doc/source/index.rst index 60d26dbe32..3461a9083c 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -41,6 +41,13 @@ Deployment: deployment_guide admin_guide +End User Guides: + +.. toctree:: + :maxdepth: 1 + + howto_cyberduck + Source: .. toctree:: diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index 33d612c724..f548852722 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -35,4 +35,5 @@ # class = swift.common.auth.DevAuthMiddleware # ip = 127.0.0.1 # port = 11000 +# ssl = false # node_timeout = 10 diff --git a/swift/common/auth.py b/swift/common/auth.py index 6830b60ba7..5e4e7d1716 100644 --- a/swift/common/auth.py +++ b/swift/common/auth.py @@ -35,6 +35,8 @@ class DevAuthMiddleware(object): self.conf = conf self.auth_host = conf.get('ip', '127.0.0.1') self.auth_port = int(conf.get('port', 11000)) + self.ssl = \ + conf.get('ssl', 'false').lower() in ('true', 'on', '1', 'yes') self.timeout = int(conf.get('node_timeout', 10)) def __call__(self, env, start_response): @@ -78,7 +80,7 @@ class DevAuthMiddleware(object): try: with Timeout(self.timeout): conn = http_connect(self.auth_host, self.auth_port, 'GET', - '/token/%s/%s' % (account, token)) + '/token/%s/%s' % (account, token), ssl=self.ssl) resp = conn.getresponse() resp.read() conn.close() diff --git a/swift/common/bufferedhttp.py b/swift/common/bufferedhttp.py index 94d1ba1073..6b308e5b01 100644 --- a/swift/common/bufferedhttp.py +++ b/swift/common/bufferedhttp.py @@ -30,8 +30,8 @@ from urllib import quote import logging import time -from eventlet.green.httplib import HTTPConnection, HTTPResponse, _UNKNOWN, \ - CONTINUE, HTTPMessage +from eventlet.green.httplib import CONTINUE, HTTPConnection, HTTPMessage, \ + HTTPResponse, HTTPSConnection, _UNKNOWN class BufferedHTTPResponse(HTTPResponse): @@ -106,10 +106,11 @@ class BufferedHTTPConnection(HTTPConnection): def http_connect(ipaddr, port, device, partition, method, path, - headers=None, query_string=None): + headers=None, query_string=None, ssl=False): """ - Helper function to create a HTTPConnection object that is buffered - for backend Swift services. + Helper function to create an HTTPConnection object. If ssl is set True, + HTTPSConnection will be used. However, if ssl=False, BufferedHTTPConnection + will be used, which is buffered for backend Swift services. :param ipaddr: IPv4 address to connect to :param port: port to connect to @@ -119,9 +120,13 @@ def http_connect(ipaddr, port, device, partition, method, path, :param path: request path :param headers: dictionary of headers :param query_string: request query string + :param ssl: set True if SSL should be used (default: False) :returns: HTTPConnection object """ - conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port)) + if ssl: + conn = HTTPSConnection('%s:%s' % (ipaddr, port)) + else: + conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port)) path = quote('/' + device + '/' + str(partition) + path) if query_string: path += '?' + query_string @@ -135,9 +140,11 @@ def http_connect(ipaddr, port, device, partition, method, path, def http_connect_raw(ipaddr, port, method, path, headers=None, - query_string=None): + query_string=None, ssl=False): """ - Helper function to create a HTTPConnection object that is buffered. + Helper function to create an HTTPConnection object. If ssl is set True, + HTTPSConnection will be used. However, if ssl=False, BufferedHTTPConnection + will be used, which is buffered for backend Swift services. :param ipaddr: IPv4 address to connect to :param port: port to connect to @@ -145,9 +152,13 @@ def http_connect_raw(ipaddr, port, method, path, headers=None, :param path: request path :param headers: dictionary of headers :param query_string: request query string + :param ssl: set True if SSL should be used (default: False) :returns: HTTPConnection object """ - conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port)) + if ssl: + conn = HTTPSConnection('%s:%s' % (ipaddr, port)) + else: + conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port)) if query_string: path += '?' + query_string conn.path = path