Skip to content

Commit ee56982

Browse files
lorexteracolinmollenhour
authored andcommitted
Enable encrypted connections with TLS (#129)
* Enable encrypted connections with TLS Use standalone PHP driver because PHP Redis extension doesn't work with TLS. Syntax `$redis = new Credis_Client('tls://host[:port][/persistence_identifier]')` * Enable encrypted connections with TLS
1 parent a692d8d commit ee56982

File tree

3 files changed

+88
-7
lines changed

3 files changed

+88
-7
lines changed

Client.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ class Credis_Client {
189189
*/
190190
protected $host;
191191

192+
/**
193+
* Scheme of the Redis server (tcp, tls, unix)
194+
* @var string
195+
*/
196+
protected $scheme;
197+
192198
/**
193199
* Port on which the Redis server is running
194200
* @var integer
@@ -310,12 +316,17 @@ public function __construct($host = '127.0.0.1', $port = 6379, $timeout = null,
310316
{
311317
$this->host = (string) $host;
312318
$this->port = (int) $port;
319+
$this->scheme = null;
313320
$this->timeout = $timeout;
314321
$this->persistent = (string) $persistent;
315322
$this->standalone = ! extension_loaded('redis');
316323
$this->authPassword = $password;
317324
$this->selectedDb = (int)$db;
318325
$this->convertHost();
326+
if ($this->scheme == 'tls') {
327+
// PHP Redis extension doesn't work with TLS
328+
$this->standalone = true;
329+
}
319330
}
320331

321332
public function __destruct()
@@ -402,24 +413,30 @@ public function setCloseOnDestruct($flag)
402413
}
403414
protected function convertHost()
404415
{
405-
if (preg_match('#^(tcp|unix)://(.*)$#', $this->host, $matches)) {
406-
if($matches[1] == 'tcp') {
416+
if (preg_match('#^(tcp|tls|unix)://(.*)$#', $this->host, $matches)) {
417+
if($matches[1] == 'tcp' || $matches[1] == 'tls') {
418+
$this->scheme = $matches[1];
407419
if ( ! preg_match('#^([^:]+)(:([0-9]+))?(/(.+))?$#', $matches[2], $matches)) {
408-
throw new CredisException('Invalid host format; expected tcp://host[:port][/persistence_identifier]');
420+
throw new CredisException('Invalid host format; expected '.$this->scheme.'://host[:port][/persistence_identifier]');
409421
}
410422
$this->host = $matches[1];
411423
$this->port = (int) (isset($matches[3]) ? $matches[3] : 6379);
412424
$this->persistent = isset($matches[5]) ? $matches[5] : '';
413425
} else {
414426
$this->host = $matches[2];
415427
$this->port = NULL;
428+
$this->scheme = 'unix';
416429
if (substr($this->host,0,1) != '/') {
417430
throw new CredisException('Invalid unix socket format; expected unix:///path/to/redis.sock');
418431
}
419432
}
420433
}
421434
if ($this->port !== NULL && substr($this->host,0,1) == '/') {
422435
$this->port = NULL;
436+
$this->scheme = 'unix';
437+
}
438+
if (!$this->scheme) {
439+
$this->scheme = 'tcp';
423440
}
424441
}
425442
/**
@@ -436,8 +453,8 @@ public function connect()
436453
if ($this->standalone) {
437454
$flags = STREAM_CLIENT_CONNECT;
438455
$remote_socket = $this->port === NULL
439-
? 'unix://'.$this->host
440-
: 'tcp://'.$this->host.':'.$this->port;
456+
? $this->scheme.'://'.$this->host
457+
: $this->scheme.'://'.$this->host.':'.$this->port;
441458
if ($this->persistent && $this->port !== NULL) {
442459
// Persistent connections to UNIX sockets are not supported
443460
$remote_socket .= '/'.$this->persistent;

README.markdown

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,39 @@ Credis_Client also supports transparent command renaming. Write code using the o
2626
client will send the aliased commands to the server transparently. Specify the renamed commands using a prefix
2727
for md5, a callable function, individual aliases, or an array map of aliases. See "Redis Security":http://redis.io/topics/security for more info.
2828

29+
## Supported connection string formats
30+
31+
```php
32+
$redis = new Credis_Client(/* connection string */);
33+
```
34+
35+
### Unix socket connection string
36+
37+
`unix:///path/to/redis.sock`
38+
39+
### TCP connection string
40+
41+
`tcp://host[:port][/persistence_identifier]`
42+
43+
### TLS connection string
44+
45+
`tls://host[:port][/persistence_identifier]`
46+
47+
#### Enable transport level security (TLS)
48+
49+
Use TLS connection string `tls://127.0.0.1:6379` instead of TCP connection `tcp://127.0.0.1:6379` string in order to enable transport level security.
50+
51+
```php
52+
require 'Credis/Client.php';
53+
$redis = new Credis_Client('tls://127.0.0.1:6379');
54+
$redis->set('awesome', 'absolutely');
55+
echo sprintf('Is Credis awesome? %s.\n', $redis->get('awesome'));
56+
57+
// When arrays are given as arguments they are flattened automatically
58+
$redis->rpush('particles', array('proton','electron','neutron'));
59+
$particles = $redis->lrange('particles', 0, -1);
60+
```
61+
2962
## Clustering your servers
3063

3164
Credis also includes a way for developers to fully utilize the scalability of Redis with multiple servers and [consistent hashing](http://en.wikipedia.org/wiki/Consistent_hashing).

tests/CredisTest.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,27 @@ public function testConnectionStrings()
651651
$this->assertEquals('abc123',$this->credis->getPersistence());
652652
}
653653

654+
public function testConnectionStringsTls()
655+
{
656+
$this->credis->close();
657+
$this->credis = new Credis_Client('tls://'.$this->redisConfig[0]['host'] . ':' . $this->redisConfig[0]['port']);
658+
if ($this->useStandalone) {
659+
$this->credis->forceStandalone();
660+
}
661+
$this->assertEquals($this->credis->getHost(),$this->redisConfig[0]['host']);
662+
$this->assertEquals($this->credis->getPort(),$this->redisConfig[0]['port']);
663+
$this->credis = new Credis_Client('tls://'.$this->redisConfig[0]['host']);
664+
if ($this->useStandalone) {
665+
$this->credis->forceStandalone();
666+
}
667+
$this->assertEquals($this->credis->getPort(),$this->redisConfig[0]['port']);
668+
$this->credis = new Credis_Client('tls://'.$this->redisConfig[0]['host'] . ':' . $this->redisConfig[0]['port'] . '/abc123');
669+
if ($this->useStandalone) {
670+
$this->credis->forceStandalone();
671+
}
672+
$this->assertEquals('abc123',$this->credis->getPersistence());
673+
}
674+
654675
/**
655676
* @group UnixSocket
656677
*/
@@ -665,7 +686,7 @@ public function testConnectionStringsSocket()
665686
$this->assertEquals('value',$this->credis->get('key'));
666687
}
667688

668-
public function testInvalidTcpConnectionstring()
689+
public function testInvalidTcpConnectionString()
669690
{
670691
$this->credis->close();
671692
$this->setExpectedExceptionShim('CredisException','Invalid host format; expected tcp://host[:port][/persistence_identifier]');
@@ -675,7 +696,17 @@ public function testInvalidTcpConnectionstring()
675696
}
676697
}
677698

678-
public function testInvalidUnixSocketConnectionstring()
699+
public function testInvalidTlsConnectionString()
700+
{
701+
$this->credis->close();
702+
$this->setExpectedExceptionShim('CredisException','Invalid host format; expected tls://host[:port][/persistence_identifier]');
703+
$this->credis = new Credis_Client('tls://'.$this->redisConfig[0]['host'] . ':abc');
704+
if ($this->useStandalone) {
705+
$this->credis->forceStandalone();
706+
}
707+
}
708+
709+
public function testInvalidUnixSocketConnectionString()
679710
{
680711
$this->credis->close();
681712
$this->setExpectedExceptionShim('CredisException','Invalid unix socket format; expected unix:///path/to/redis.sock');

0 commit comments

Comments
 (0)