diff --git a/src/backend/BSServer.pm b/src/backend/BSServer.pm
index 58bd8e6b44173f86c50a447c6d0912ad25215923..74e30841c966d3c447fd0d43f8bfe7f62640e6de 100644
--- a/src/backend/BSServer.pm
+++ b/src/backend/BSServer.pm
@@ -42,6 +42,9 @@ use BSUtil;
 
 use strict;
 
+require BSSSL;
+my $tossl = \&BSSSL::tossl;
+
 my $MS2;	# secondary server port
 
 our $request;		# FIXME: should not be global
@@ -319,6 +322,9 @@ sub server {
   };
 
   setsockopt(CLNT, SOL_SOCKET, SO_KEEPALIVE, pack("l",1)) if $conf->{'setkeepalive'};
+  if ($conf->{'proto'} eq 'https') {
+      $tossl->(\*CLNT, $conf->{'ssl_keyfile'}, $conf->{'ssl_certfile'}, 0);
+  }
   if ($conf->{'accept'}) {
     eval {
       $conf->{'accept'}->($conf, $req);
diff --git a/src/backend/BSStdServer.pm b/src/backend/BSStdServer.pm
index 30a416d7672dc7034c9da6713f1d59cc36a84cab..7b86280c53583be6802f91e7c2bec4a4f33bf98f 100644
--- a/src/backend/BSStdServer.pm
+++ b/src/backend/BSStdServer.pm
@@ -213,6 +213,7 @@ sub server {
     $conf->{'periodic_interval'} ||= 1;
     $conf->{'serverstatus'} ||= "$rundir/$name.status";
     $conf->{'setkeepalive'} = 1 unless defined $conf->{'setkeepalive'};
+    $conf->{'proto'} = 'http' unless defined $conf->{'proto'};
     $conf->{'name'} = $name;
     BSDispatch::compile($conf);
   }
diff --git a/src/backend/bs_getbinariesproxy b/src/backend/bs_getbinariesproxy
index 71c47e49ac8d304799c25a9bf9586a187b05b052..afb92d9338b633834ba8d3a2ee7bf7986ad4c8f9 100755
--- a/src/backend/bs_getbinariesproxy
+++ b/src/backend/bs_getbinariesproxy
@@ -52,6 +52,11 @@ my $gettimeout = 3600;
 
 my $port = 5254;        
 $port = $1 if $BSConfig::getbinariesproxyserver && $BSConfig::getbinariesproxyserver =~ /:(\d+)$/;
+my $proto = 'http';
+$proto = $1 if $BSConfig::getbinariesproxyserver =~ /^(https?):/;
+if ($proto eq 'https') {
+  die("need ssl_keyfile and ssl_certfile for HTTPS") unless defined $BSConfig::ssl_keyfile and defined $BSConfig::ssl_certfile;
+}
 
 my $cachedir = "$BSConfig::bsdir/getbinariesproxycache";
 my $cachesize = 1024 * 1024 * 1024;	# default: 1G
@@ -349,6 +354,9 @@ my $dispatches = [
 
 my $conf = {
   'port' => $port,
+  'ssl_keyfile' => $BSConfig::ssl_keyfile || '',
+  'ssl_certfile' => $BSConfig::ssl_certfile || '',
+  'proto' => $proto,
   'dispatches' => $dispatches,
   'setkeepalive' => 1,
   'maxchild' => 40,
diff --git a/src/backend/bs_repserver b/src/backend/bs_repserver
index e8de797b219502cd30aed4ec3c9f98ba20945405..5b47cdbf7a1fe3ac2c2e9e0f53c5c016c8ef4f01 100755
--- a/src/backend/bs_repserver
+++ b/src/backend/bs_repserver
@@ -69,6 +69,11 @@ use strict;
 
 my $port = 5252;	#'RR'
 $port = $1 if $BSConfig::reposerver =~ /:(\d+)$/;
+my $proto = 'http';
+$proto = $1 if $BSConfig::reposerver =~ /^(https?):/;
+if ($proto eq 'https') {
+  die("need ssl_keyfile and ssl_certfile for HTTPS") unless defined $BSConfig::ssl_keyfile and defined $BSConfig::ssl_certfile;
+}
 my $proxy;
 $proxy = $BSConfig::proxy if defined($BSConfig::proxy);
 
@@ -4395,6 +4400,9 @@ my $dispatches_ajax = [
 
 my $conf = {
   'port' => $port,
+  'ssl_keyfile' => $BSConfig::ssl_keyfile || '',
+  'ssl_certfile' => $BSConfig::ssl_certfile || '',
+  'proto' => $proto,
   'dispatches' => $dispatches,
   'maxchild' => 20,
   'maxchild2' => 20,
@@ -4409,6 +4417,9 @@ if ($BSConfig::workerreposerver) {
   my $wport = $port;
   $wport = $1 if $BSConfig::workerreposerver =~ /:(\d+)$/;
   $conf->{'port2'} = $wport if $wport != $port;
+  my $wproto = $proto;
+  $wproto = $1 if $BSConfig::workerreposerver =~ /^(https?):/;
+  die("worker port on $wproto but normal port on $proto: both need to be the same\n") unless $wproto eq $proto;
 }
 
 # create bsdir before root privileges are dropped
diff --git a/src/backend/bs_service b/src/backend/bs_service
index 9e8da0aec9924f88fc18f41186fbfe6dc7918af3..a525b4ef76f533670d6018e930ad4bdc1de592f0 100755
--- a/src/backend/bs_service
+++ b/src/backend/bs_service
@@ -36,7 +36,7 @@ use Data::Dumper;
 use POSIX;
 use Fcntl qw(:DEFAULT :flock);
 
-use BSRPC;
+use BSRPC ':https';
 use BSServer;
 use BSStdServer;
 use BSConfiguration;
@@ -55,6 +55,11 @@ BSUtil::set_fdatasync_before_rename() unless $BSConfig::disable_data_sync || $BS
 my $tempdir = $BSConfig::servicetempdir || $BSConfig::servicetempdir || "$BSConfig::bsdir/service";
 my $port = 5152;
 $port = $1 if $BSConfig::serviceserver =~ /:(\d+)$/;
+my $proto = 'http';
+$proto = $1 if $BSConfig::serviceserver =~ /^(https?):/;
+if ($proto eq 'https') {
+  die("need ssl_keyfile and ssl_certfile for HTTPS") unless defined $BSConfig::ssl_keyfile and defined $BSConfig::ssl_certfile;
+}
 
 my $servicedir = $BSConfig::servicedir || "/usr/lib/obs/service";
 my $rootservicedir = $BSConfig::serviceroot ? "$BSConfig::serviceroot/$servicedir" : $servicedir;
@@ -250,6 +255,9 @@ my $dispatches = [
 
 my $conf = {
   'port' => $port,
+  'ssl_keyfile' => $BSConfig::ssl_keyfile || '',
+  'ssl_certfile' => $BSConfig::ssl_certfile || '',
+  'proto' => $proto,
   'dispatches' => $dispatches,
   'setkeepalive' => 1,
   'maxchild' => $maxchild,
diff --git a/src/backend/bs_srcserver b/src/backend/bs_srcserver
index 383d600f5492bb001d0cad1f5c37b3eaef1c7c6e..54e3baa22555d5ff82a7197e81e534bc8068608e 100755
--- a/src/backend/bs_srcserver
+++ b/src/backend/bs_srcserver
@@ -69,6 +69,11 @@ use strict;
 
 my $port = 5352;	#'SR'
 $port = $1 if $BSConfig::srcserver =~ /:(\d+)$/;
+my $proto = 'http';
+$proto = $1 if $BSConfig::srcserver =~ /^(https?):/;
+if ($proto eq 'https') {
+  die("need ssl_keyfile and ssl_certfile for HTTPS") unless defined $BSConfig::ssl_keyfile and defined $BSConfig::ssl_certfile;
+}
 my $proxy;
 $proxy = $BSConfig::proxy if defined($BSConfig::proxy);
 
@@ -8792,6 +8797,9 @@ my $dispatches_ajax = [
 
 my $conf = {
   'port' => $port,
+  'ssl_keyfile' => $BSConfig::ssl_keyfile || '',
+  'ssl_certfile' => $BSConfig::ssl_certfile || '',
+  'proto' => $proto,
   'dispatches' => $dispatches,
   'maxchild' => 20,
   'maxchild2' => 20,
@@ -8806,6 +8814,9 @@ if ($BSConfig::workersrcserver) {
   my $wport = $port;
   $wport = $1 if $BSConfig::workersrcserver =~ /:(\d+)$/;
   $conf->{'port2'} = $wport if $wport != $port;
+  my $wproto = $proto;
+  $wproto = $1 if $BSConfig::workersrcserver =~ /^(https?):/;
+  die("worker port on $wproto but normal port on $proto: both need to be the same\n") unless $wproto eq $proto;
 }
 
 # create bsdir before root privileges are dropped
diff --git a/src/backend/bs_worker b/src/backend/bs_worker
index fc038a1a1a9277cfa03c977c630a286ede438e48..6e718ac41b78fd1f9733358c8bbf6ed3c62e495e 100755
--- a/src/backend/bs_worker
+++ b/src/backend/bs_worker
@@ -38,7 +38,7 @@ BEGIN { Fcntl->import(':seek') unless defined &SEEK_SET; }
 
 use Storable;
 
-use BSRPC;
+use BSRPC ':https';
 use BSServer;
 use BSDispatch;		# for parse_cgi
 use BSConfiguration;
diff --git a/src/backend/worker/BSSSL.pm b/src/backend/worker/BSSSL.pm
new file mode 120000
index 0000000000000000000000000000000000000000..2a67884296c5b59db96bbca40ea5f86377fa2998
--- /dev/null
+++ b/src/backend/worker/BSSSL.pm
@@ -0,0 +1 @@
+../BSSSL.pm
\ No newline at end of file