This is an automated email from the ASF dual-hosted git repository.
rawlin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 9838c0e Traffic router add https (#3436)
9838c0e is described below
commit 9838c0e0d6f98f6f0bde7c87e997403ee4db57cb
Author: mattjackson220 <[email protected]>
AuthorDate: Fri Aug 2 14:28:58 2019 -0600
Traffic router add https (#3436)
* Updated Traffic Router API to use HTTPS, updated TO to call TR API HTTPS
if available, updated tests and documentation
* Updated CHANGELOG
* added licensing header
* Updated Traffic Router API to use HTTPS, updated TO to call TR API HTTPS
if available, updated tests and documentation
* updated to separate API default cert from DS default cert
* updated per comments
* rebase with master
* updates per comment
* extended expiration of cert
---
CHANGELOG.md | 1 +
docs/source/admin/quick_howto/ciab.rst | 2 +-
docs/source/api/cdns_name_snapshot.rst | 20 +++---
docs/source/api/cdns_name_snapshot_new.rst | 20 +++---
docs/source/development/traffic_router.rst | 2 +-
.../traffic_router/traffic_router_api.rst | 8 +++
.../cdn-in-a-box/docker-compose.expose-ports.yml | 1 +
.../traffic_ops_data/profiles/040-CCR_CIAB.json | 5 ++
.../cdn-in-a-box/traffic_router/Dockerfile | 2 +-
infrastructure/cdn-in-a-box/traffic_router/run.sh | 2 +
lib/go-tc/crconfig.go | 21 +++---
traffic_ops/app/lib/API/Cdn.pm | 17 ++++-
.../app/lib/MojoPlugins/TrafficRouterConnection.pm | 30 ++++++--
traffic_ops/app/lib/Utils/CCR.pm | 25 +++++--
traffic_ops/traffic_ops_golang/crconfig/servers.go | 31 ++++++---
.../traffic_ops_golang/crconfig/servers_test.go | 3 +
.../traffic_router/protocol/RouterNioEndpoint.java | 15 ++--
.../traffic_router/secure/CertificateRegistry.java | 80 +++++++++++++++++++---
.../traffic_router/utils/HttpsProperties.java | 53 ++++++++++++++
traffic_router/core/src/main/conf/https.properties | 16 +++++
traffic_router/core/src/main/conf/server.xml | 4 ++
.../traffic_router/core/http/RouterFilter.java | 2 +-
.../core/router/TrafficRouterManager.java | 10 +++
.../traffic_router/core/util/LanguidState.java | 14 ++++
.../main/lib/systemd/system/traffic_router.service | 1 +
.../core/src/main/scripts/postinstall.sh | 16 ++++-
traffic_router/core/src/test/conf/https.properties | 16 +++++
.../traffic_router/core/CatalinaTrafficRouter.java | 13 ++++
28 files changed, 356 insertions(+), 74 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d17ecd..a9494fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -57,6 +57,7 @@ The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/).
- Database migrations have been collapsed. Rollbacks to migrations that
previously existed are no longer possible.
- Issue #3750: Fixed Grove access log fractional seconds.
- Issue #3646: Fixed Traffic Monitor Thresholds.
+- Modified Traffic Router API to be available via HTTPS.
## [3.0.0] - 2018-10-30
### Added
diff --git a/docs/source/admin/quick_howto/ciab.rst
b/docs/source/admin/quick_howto/ciab.rst
index abee210..cf04022 100644
--- a/docs/source/admin/quick_howto/ciab.rst
+++ b/docs/source/admin/quick_howto/ciab.rst
@@ -69,7 +69,7 @@ In a typical scenario, if the steps in `Building`_ have been
followed, all that'
| Traffic Portal | Web interface on 443 (Javascript
required) | ``TO_ADMIN_USER`` in `variables.env`_ |
``TO_ADMIN_PASSWORD`` in `variables.env`_ |
+---------------------------------+--------------------------------------------------------------+---------------------------------------+-------------------------------------------+
| Traffic Router | Web interfaces on ports 3080 (HTTP)
and 3443 (HTTPS), with a | N/A | N/A
|
- | | DNS service on 53 and an API on
3333 | |
|
+ | | DNS service on 53 and an API on
3333 (HTTP) and 2222 (HTTPS) | |
|
+---------------------------------+--------------------------------------------------------------+---------------------------------------+-------------------------------------------+
| Traffic Vault | Riak key-value store on port 8010
| ``TV_ADMIN_USER`` in `variables.env`_ |
``TV_ADMIN_PASSWORD`` in `variables.env`_ |
+---------------------------------+--------------------------------------------------------------+---------------------------------------+-------------------------------------------+
diff --git a/docs/source/api/cdns_name_snapshot.rst
b/docs/source/api/cdns_name_snapshot.rst
index e80f901..a79d138 100644
--- a/docs/source/api/cdns_name_snapshot.rst
+++ b/docs/source/api/cdns_name_snapshot.rst
@@ -108,15 +108,16 @@ Response Structure
:contentRouters: An object containing keys which are the (short) hostnames of
the Traffic Routers that serve requests for :term:`Delivery Service`\ s in this
CDN
- :api.port: A string containing the port number on which the
:ref:`tr-api` is served by this Traffic Router
- :fqdn: This Traffic Router's Fully Qualified Domain Name (FQDN)
- :httpsPort: The port number on which this Traffic Router listens for
incoming HTTPS requests
- :ip: This Traffic Router's IPv4 address
- :ip6: This Traffic Router's IPv6 address
- :location: The name of the Cache Group to which this Traffic Router
belongs
- :port: The port number on which this Traffic Router listens for
incoming HTTP requests
- :profile: The :ref:`profile-name` of the :term:`Profile` used by this
Traffic Router
- :status: The health status of this Traffic Router
+ :api.port: A string containing the port number on which the
:ref:`tr-api` is served by this Traffic Router via HTTP
+ :secure.api.port: A string containing the port number on which the
:ref:`tr-api` is served by this Traffic Router via HTTPS (optional)
+ :fqdn: This Traffic Router's Fully Qualified Domain Name
(FQDN)
+ :httpsPort: The port number on which this Traffic Router listens
for incoming HTTPS requests
+ :ip: This Traffic Router's IPv4 address
+ :ip6: This Traffic Router's IPv6 address
+ :location: The name of the Cache Group to which this Traffic
Router belongs
+ :port: The port number on which this Traffic Router listens
for incoming HTTP requests
+ :profile: The :ref:`profile-name` of the :term:`Profile` used
by this Traffic Router
+ :status: The health status of this Traffic Router
.. seealso:: :ref:`health-proto`
@@ -436,6 +437,7 @@ Response Structure
"contentRouters": {
"trafficrouter": {
"api.port": "3333",
+ "secure.api.port": "3443",
"fqdn": "trafficrouter.infra.ciab.test",
"httpsPort": 443,
"ip": "172.16.239.60",
diff --git a/docs/source/api/cdns_name_snapshot_new.rst
b/docs/source/api/cdns_name_snapshot_new.rst
index 6c80789..f03d19c 100644
--- a/docs/source/api/cdns_name_snapshot_new.rst
+++ b/docs/source/api/cdns_name_snapshot_new.rst
@@ -107,15 +107,16 @@ Response Structure
:contentRouters: An object containing keys which are the (short) hostnames of
the Traffic Routers that serve requests for :term:`Delivery Service`\ s in this
CDN
- :api.port: A string containing the port number on which the
:ref:`tr-api` is served by this Traffic Router
- :fqdn: This Traffic Router's Fully Qualified Domain Name (FQDN)
- :httpsPort: The port number on which this Traffic Router listens for
incoming HTTPS requests
- :ip: This Traffic Router's IPv4 address
- :ip6: This Traffic Router's IPv6 address
- :location: The name of the :term:`Cache Group` to which this Traffic
Router belongs
- :port: The port number on which this Traffic Router listens for
incoming HTTP requests
- :profile: The :ref:`profile-name` of the :term:`Profile` used by this
Traffic Router
- :status: The health status of this Traffic Router
+ :api.port: A string containing the port number on which the
:ref:`tr-api` is served by this Traffic Router via HTTP
+ :secure.api.port: A string containing the port number on which the
:ref:`tr-api` is served by this Traffic Router via HTTPS (optional)
+ :fqdn: This Traffic Router's Fully Qualified Domain Name
(FQDN)
+ :httpsPort: The port number on which this Traffic Router listens
for incoming HTTPS requests
+ :ip: This Traffic Router's IPv4 address
+ :ip6: This Traffic Router's IPv6 address
+ :location: The name of the :term:`Cache Group` to which this
Traffic Router belongs
+ :port: The port number on which this Traffic Router listens
for incoming HTTP requests
+ :profile: The :ref:`profile-name` of the :term:`Profile` used
by this Traffic Router
+ :status: The health status of this Traffic Router
.. seealso:: :ref:`health-proto`
@@ -433,6 +434,7 @@ Response Structure
"contentRouters": {
"trafficrouter": {
"api.port": "3333",
+ "secure.api.port": "3443",
"fqdn": "trafficrouter.infra.ciab.test",
"httpsPort": 443,
"ip": "172.16.239.60",
diff --git a/docs/source/development/traffic_router.rst
b/docs/source/development/traffic_router.rst
index e4385a1..4b60b6e 100644
--- a/docs/source/development/traffic_router.rst
+++ b/docs/source/development/traffic_router.rst
@@ -115,7 +115,7 @@ To install the Traffic Router Developer environment:
.. Note:: If an error is displayed in the Console, run ``mvn
clean verify`` from the ``traffic_router`` directory
-Once running, the :ref:`tr-api` is available at http://localhost:3333, the
HTTP routing interface is available on http://localhost:8888 and HTTPS is
available on http://localhost:8443. The DNS server and routing interface is
available on localhost:53 via TCP and UDP.
+Once running, the :ref:`tr-api` is available over HTTP at
http://localhost:3333 and over HTTPS at https://localhost:3443, the HTTP
routing interface is available on http://localhost:8888 and HTTPS is available
on http://localhost:8443. The DNS server and routing interface is available on
localhost:53 via TCP and UDP.
Manual Testing
==============
diff --git a/docs/source/development/traffic_router/traffic_router_api.rst
b/docs/source/development/traffic_router/traffic_router_api.rst
index 5efabb4..df91b30 100644
--- a/docs/source/development/traffic_router/traffic_router_api.rst
+++ b/docs/source/development/traffic_router/traffic_router_api.rst
@@ -20,6 +20,14 @@ Traffic Router API
******************
By default, Traffic Router serves its API via HTTP (not HTTPS) on port 3333.
This can be configured in :file:`/opt/traffic_router/conf/server.xml` or by
setting a :term:`Parameter` with the :ref:`parameter-name` "api.port", and the
:ref:`parameter-config-file` "server.xml" on the Traffic Router's
:term:`Profile`.
+The API can be configured via HTTPS on port 3443 in
:file:`/opt/traffic_router/conf/server.xml` or by setting a :term:`Parameter`
named ``secure.api.port`` with ``configFile`` ``server.xml`` on the Traffic
Router's :term:`Profile`. The post install script will generate self signed
certificates at ``/opt/traffic_router/conf/``, create a new Java Keystore named
:file:`/opt/traffic_router/conf/keyStore.jks`, and add the new certificate to
the Keystore. The password for the Java Keystore a [...]
+To override the self signed certificates with new ones from a certificate
authority, update the properties for the Keystore location and password at
:file:`/opt/traffic_router/conf/https.properties`.
+
+
+The API can be configured via HTTPS on port 3443 in
:file:`/opt/traffic_router/conf/server.xml` or by setting a :term:`Parameter`
named ``secure.api.port`` with ``configFile`` ``server.xml`` on the Traffic
Router's :term:`Profile`. When ``systemctl start traffic_router`` is run, it
will generate self signed certificates at ``/opt/traffic_router/conf/``, create
a new Java Keystore named :file:`/opt/traffic_router/conf/keyStore.jks`, and
add the new certificate to the Keystore. The passw [...]
+To override the self signed certificates with new ones from a certificate
authority, either replace the Java Keystore in the default location or update
the properties for the new Keystore location and password at
:file:`/opt/traffic_router/conf/https.properties` and then restart the Traffic
Router using ``systemctl``.
+
+
Traffic Router API endpoints only respond to ``GET`` requests.
``/crs/stats``
diff --git a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
b/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
index 653479f..484e237 100644
--- a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
+++ b/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
@@ -46,6 +46,7 @@ services:
- "3080:80"
- "3443:443"
- "3333:3333"
+ - "2222:3443"
influxdb:
ports:
- "8086:8086"
diff --git
a/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/040-CCR_CIAB.json
b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/040-CCR_CIAB.json
index e4836fc..6d00ce8 100644
--- a/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/040-CCR_CIAB.json
+++ b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/040-CCR_CIAB.json
@@ -81,6 +81,11 @@
"value": "3333"
},
{
+ "configFile": "server.xml",
+ "name": "secure.api.port",
+ "value": "3443"
+ },
+ {
"configFile": "CRConfig.json",
"name": "api.cache-control.max-age",
"value": "10"
diff --git a/infrastructure/cdn-in-a-box/traffic_router/Dockerfile
b/infrastructure/cdn-in-a-box/traffic_router/Dockerfile
index 0548176..9e790c8 100644
--- a/infrastructure/cdn-in-a-box/traffic_router/Dockerfile
+++ b/infrastructure/cdn-in-a-box/traffic_router/Dockerfile
@@ -45,6 +45,6 @@ ADD enroller/server_template.json \
traffic_ops/to-access.sh \
/
-EXPOSE 53 80 3333
+EXPOSE 53 80 3333 3443
CMD /run.sh
diff --git a/infrastructure/cdn-in-a-box/traffic_router/run.sh
b/infrastructure/cdn-in-a-box/traffic_router/run.sh
index e7a935a..5c2f63e 100755
--- a/infrastructure/cdn-in-a-box/traffic_router/run.sh
+++ b/infrastructure/cdn-in-a-box/traffic_router/run.sh
@@ -90,6 +90,8 @@ do
fi;
done
+/opt/traffic_router/conf/generatingCerts.sh
+
# Configure TO properties
# File: /opt/traffic_router/conf/traffic_ops.properties
echo "" > $TO_PROPERTIES
diff --git a/lib/go-tc/crconfig.go b/lib/go-tc/crconfig.go
index e0080f8..7be488f 100644
--- a/lib/go-tc/crconfig.go
+++ b/lib/go-tc/crconfig.go
@@ -67,16 +67,17 @@ type CRConfigTTL struct {
type CRConfigRouterStatus string
type CRConfigRouter struct {
- APIPort *string `json:"api.port,omitempty"`
- FQDN *string `json:"fqdn,omitempty"`
- HTTPSPort *int `json:"httpsPort"`
- HashCount *int `json:"hashCount,omitempty"`
- IP *string `json:"ip,omitempty"`
- IP6 *string `json:"ip6,omitempty"`
- Location *string `json:"location,omitempty"`
- Port *int `json:"port,omitempty"`
- Profile *string `json:"profile,omitempty"`
- ServerStatus *CRConfigRouterStatus `json:"status,omitempty"`
+ APIPort *string `json:"api.port,omitempty"`
+ FQDN *string `json:"fqdn,omitempty"`
+ HTTPSPort *int `json:"httpsPort"`
+ HashCount *int `json:"hashCount,omitempty"`
+ IP *string `json:"ip,omitempty"`
+ IP6 *string `json:"ip6,omitempty"`
+ Location *string `json:"location,omitempty"`
+ Port *int `json:"port,omitempty"`
+ Profile *string `json:"profile,omitempty"`
+ SecureAPIPort *string `json:"secure.api.port,omitempty"`
+ ServerStatus *CRConfigRouterStatus `json:"status,omitempty"`
}
type CRConfigServerStatus string
diff --git a/traffic_ops/app/lib/API/Cdn.pm b/traffic_ops/app/lib/API/Cdn.pm
index 8b463a2..c54846a 100644
--- a/traffic_ops/app/lib/API/Cdn.pm
+++ b/traffic_ops/app/lib/API/Cdn.pm
@@ -523,8 +523,10 @@ sub routing {
# TODO: what happens when the request to CCR times out?
-jse
my $c = $self->get_traffic_router_connection( {
hostname => $ccr_host } );
my $s = $c->get_crs_stats();
+ my $url = $c->get_url();
+
if ( !defined($s) ) {
- $self->app->log->error("Unable to contact
$ccr_host for $cdn_name.");
+ $self->app->log->error("Unable to contact
$ccr_host for $cdn_name. Traffic Router Url = $url");
return $self->internal_server_error( {
"Internal Server" => "Error: Unable to contact $ccr_host" } );
}
else {
@@ -740,6 +742,15 @@ sub gen_traffic_router_config {
my $api_port =
( defined($r) && defined( $r->value ) ) ?
$r->value : 3333;
+ my $sap_param =
$self->db->resultset('Parameter')->search(
+ {
+ 'profile_parameters.profile' =>
$row->profile->id,
+ 'name' =>
'secure.api.port'
+ },
+ { join => 'profile_parameters' }
+ );
+ my $secure_api_port = $rs_param->single;
+
my $traffic_router;
$traffic_router->{'hostName'} = $row->host_name;
@@ -751,6 +762,10 @@ sub gen_traffic_router_config {
$traffic_router->{'ip'} = $row->ip_address;
$traffic_router->{'ip6'} = $row->ip6_address;
$traffic_router->{'profile'} = $row->profile->name;
+ if ( defined($secure_api_port) && defined(
$secure_api_port->value ) ) {
+ $traffic_router->{'secureApiPort'} =
int($secure_api_port->value);
+ }
+
push( @{ $data_obj->{'trafficRouters'} },
$traffic_router );
}
elsif ( $row->type->name =~ m/^EDGE/ || $row->type->name =~
m/^MID/ ) {
diff --git a/traffic_ops/app/lib/MojoPlugins/TrafficRouterConnection.pm
b/traffic_ops/app/lib/MojoPlugins/TrafficRouterConnection.pm
index 952fbf9..7742a8c 100755
--- a/traffic_ops/app/lib/MojoPlugins/TrafficRouterConnection.pm
+++ b/traffic_ops/app/lib/MojoPlugins/TrafficRouterConnection.pm
@@ -33,6 +33,7 @@ sub register {
my $hostname = undef;
my $port = undef;
+ my $secure_port = undef;
if ( exists( $args->{cdn} ) ) {
my $cdn = $args->{cdn};
@@ -47,24 +48,41 @@ sub register {
}
elsif ( exists $args->{hostname} ) {
$hostname = $args->{hostname};
-
}
else {
confess("Supply a cdn or host in the argument
hashref");
}
+
+ my $traffic_router_connection = undef;
+
if ( defined( $args->{port} ) ) {
$port = $args->{port};
}
else {
my $hostonly = ( split( /\./, $hostname ) )[0];
my $server =
$self->db->resultset('Server')->search( { host_name => $hostonly } )->single();
- my $pp =
+
+ my $pp_secure_api_port =
$self->db->resultset('ProfileParameter')
- ->search( { -and => [ 'profile.id' =>
$server->profile->id, 'parameter.name' => 'api.port', 'parameter.config_file'
=> 'server.xml' ] },
- { prefetch => [ 'parameter', 'profile'
] } )->single();
- $port = $pp->parameter->value;
+ ->search( { -and => [
'profile.id' => $server->profile->id, 'parameter.name' => 'secure.api.port',
'parameter.config_file' => 'server.xml' ] },
+ { prefetch => [ 'parameter',
'profile' ] } )->single();
+ if ( defined($pp_secure_api_port) ) {
+ $secure_port =
$pp_secure_api_port->parameter->value;
+ }
+
+ if ( defined( $secure_port ) ) {
+ $port = $secure_port;
+ $traffic_router_connection = new
Utils::CCR( $hostname, $port, 1 );
+ }
+ else {
+ my $pp_api_port =
+
$self->db->resultset('ProfileParameter')
+ ->search( { -and => [
'profile.id' => $server->profile->id, 'parameter.name' => 'api.port',
'parameter.config_file' => 'server.xml' ] },
+ { prefetch => [
'parameter', 'profile' ] } )->single();
+ $port =
$pp_api_port->parameter->value;
+ $traffic_router_connection = new
Utils::CCR( $hostname, $port);
+ }
}
- my $traffic_router_connection = new Utils::CCR(
$hostname, $port );
my $proxy_param =
$self->db->resultset('Parameter')->search( {
-and => [ name => 'tm.traffic_rtr_fwd_proxy', config_file => 'global' ] }
)->single();
if ( defined($proxy_param) ) {
diff --git a/traffic_ops/app/lib/Utils/CCR.pm b/traffic_ops/app/lib/Utils/CCR.pm
index 50e1aa7..82f77b5 100644
--- a/traffic_ops/app/lib/Utils/CCR.pm
+++ b/traffic_ops/app/lib/Utils/CCR.pm
@@ -35,6 +35,7 @@ sub new {
my $class = shift;
my $ccr_host = shift;
my $ccr_port = shift || 80;
+ my $is_secure_port = shift || 0;
if ( !defined($ccr_host) ) {
confess("First constructor argument must be the CCR host");
@@ -43,10 +44,11 @@ sub new {
confess("Second constructor argument must be the port number of
the CCR host");
}
- $self->{CCR_HOST} = $ccr_host;
- $self->{CCR_PORT} = $ccr_port;
- $self->{USER_AGENT} = Mojo::UserAgent->new;
- $self->{FWD_PROXY} = undef;
+ $self->{CCR_HOST} = $ccr_host;
+ $self->{CCR_PORT} = $ccr_port;
+ $self->{USER_AGENT} = Mojo::UserAgent->new;
+ $self->{FWD_PROXY} = undef;
+ $self->{IS_SECURE_PORT} = $is_secure_port;
return ( bless( $self, $class ) );
}
@@ -77,10 +79,21 @@ sub get_port {
return ( $self->{CCR_PORT} );
}
+sub get_is_secure_port {
+ my $self = shift || confess("Call on an instance of Utils::CCR");
+ return ( $self->{IS_SECURE_PORT} );
+}
+
sub get_url {
my $self = shift || confess("Call on an instance of Utils::CCR");
- my $url = "http://" . $self->get_host() . ":" . $self->get_port();
- return ($url);
+
+ my $protocol = "http";
+ if ( $self->get_is_secure_port() ) {
+ $protocol = "https";
+ }
+
+ my $url = "$protocol://" . $self->get_host() . ":" . $self->get_port();
+ return ( $url );
}
sub get_location {
diff --git a/traffic_ops/traffic_ops_golang/crconfig/servers.go
b/traffic_ops/traffic_ops_golang/crconfig/servers.go
index 286990a..b543ff0 100644
--- a/traffic_ops/traffic_ops_golang/crconfig/servers.go
+++ b/traffic_ops/traffic_ops_golang/crconfig/servers.go
@@ -59,15 +59,16 @@ func makeCRConfigServers(cdn string, tx *sql.Tx, cdnDomain
string) (
case *s.ServerType == tc.RouterTypeName:
status := tc.CRConfigRouterStatus(*s.ServerStatus)
routers[host] = tc.CRConfigRouter{
- APIPort: s.APIPort,
- FQDN: s.Fqdn,
- HTTPSPort: s.HttpsPort,
- IP: s.Ip,
- IP6: s.Ip6,
- Location: s.LocationId,
- Port: s.Port,
- Profile: s.Profile,
- ServerStatus: &status,
+ APIPort: s.APIPort,
+ FQDN: s.Fqdn,
+ HTTPSPort: s.HttpsPort,
+ IP: s.Ip,
+ IP6: s.Ip6,
+ Location: s.LocationId,
+ Port: s.Port,
+ Profile: s.Profile,
+ SecureAPIPort: s.SecureAPIPort,
+ ServerStatus: &status,
}
case *s.ServerType == tc.MonitorTypeName:
monitors[host] = tc.CRConfigMonitor{
@@ -93,7 +94,8 @@ func makeCRConfigServers(cdn string, tx *sql.Tx, cdnDomain
string) (
// ServerUnion has all fields from all servers. This is used to select all
server data with a single query, and then convert each to the proper type
afterwards.
type ServerUnion struct {
tc.CRConfigTrafficOpsServer
- APIPort *string
+ APIPort *string
+ SecureAPIPort *string
}
const DefaultWeightMultiplier = 1000.0
@@ -165,6 +167,10 @@ and (st.name = 'REPORTED' or st.name = 'ONLINE' or st.name
= 'ADMIN_DOWN')
s.APIPort = params.APIPort
}
+ if hasParams && params.SecureAPIPort != nil {
+ s.SecureAPIPort = params.SecureAPIPort
+ }
+
weightMultiplier := DefaultWeightMultiplier
if hasParams && params.WeightMultiplier != nil {
weightMultiplier = *params.WeightMultiplier
@@ -301,6 +307,7 @@ order by dsr.set_number asc
// ServerParams contains parameter data filled in the CRConfig Servers
objects. If a given param doesn't exist on the given server, it will be nil.
type ServerParams struct {
APIPort *string
+ SecureAPIPort *string
Weight *float64
WeightMultiplier *float64
}
@@ -315,7 +322,7 @@ left join profile_parameter as pp on pp.profile = s.profile
left join parameter as p on p.id = pp.parameter
inner join status as st ON st.id = s.status
where s.cdn_id = (select id from cdn where name = $1)
-and ((p.config_file = 'CRConfig.json' and (p.name = 'weight' or p.name =
'weightMultiplier')) or (p.name = 'api.port'))
+and ((p.config_file = 'CRConfig.json' and (p.name = 'weight' or p.name =
'weightMultiplier')) or (p.name = 'api.port') or (p.name = 'secure.api.port'))
and (st.name = 'REPORTED' or st.name = 'ONLINE' or st.name = 'ADMIN_DOWN')
`
rows, err := tx.Query(q, cdn)
@@ -336,6 +343,8 @@ and (st.name = 'REPORTED' or st.name = 'ONLINE' or st.name
= 'ADMIN_DOWN')
switch name {
case "api.port":
param.APIPort = &val
+ case "secure.api.port":
+ param.SecureAPIPort = &val
case "weight":
i, err := strconv.ParseFloat(val, 64)
if err != nil {
diff --git a/traffic_ops/traffic_ops_golang/crconfig/servers_test.go
b/traffic_ops/traffic_ops_golang/crconfig/servers_test.go
index 603025a..dafa56a 100644
--- a/traffic_ops/traffic_ops_golang/crconfig/servers_test.go
+++ b/traffic_ops/traffic_ops_golang/crconfig/servers_test.go
@@ -82,6 +82,7 @@ func ExpectedGetServerParams() map[string]ServerParams {
return map[string]ServerParams{
"cache0": ServerParams{
APIPort: randStr(),
+ SecureAPIPort: randStr(),
Weight: randFloat64(),
WeightMultiplier: randFloat64(),
},
@@ -96,6 +97,7 @@ func ExpectedGetServerParams() map[string]ServerParams {
func MockGetServerParams(mock sqlmock.Sqlmock, expected
map[string]ServerParams, cdn string) {
rows := sqlmock.NewRows([]string{"host_name", "name", "value"})
rows = rows.AddRow("cache0", "api.port", *expected["cache0"].APIPort)
+ rows = rows.AddRow("cache0", "secure.api.port",
*expected["cache0"].SecureAPIPort)
rows = rows.AddRow("cache0", "weight", *expected["cache0"].Weight)
rows = rows.AddRow("cache0", "weightMultiplier",
*expected["cache0"].WeightMultiplier)
rows = rows.AddRow("cache1", "api.port", *expected["cache1"].APIPort)
@@ -151,6 +153,7 @@ func ExpectedGetAllServers(params map[string]ServerParams)
map[string]ServerUnio
for name, param := range params {
s := ServerUnion{
APIPort: param.APIPort,
+ SecureAPIPort: param.SecureAPIPort,
CRConfigTrafficOpsServer: randServer(),
}
i := int(*param.Weight * *param.WeightMultiplier)
diff --git
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
index 6fe6399..4648604 100644
---
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
+++
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
@@ -27,7 +27,6 @@ import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SocketEvent;
import org.apache.tomcat.util.net.SocketProcessorBase;
import org.apache.tomcat.util.net.SocketWrapperBase;
-
import java.util.Map;
import java.util.Set;
@@ -40,8 +39,8 @@ public class RouterNioEndpoint extends NioEndpoint {
// certificates. When we are done we call the parent classes
initialiseSsl.
@SuppressWarnings({"PMD.SignatureDeclareThrowsException"})
@Override
- protected void initialiseSsl() throws Exception{
- if (isSSLEnabled()){
+ protected void initialiseSsl() throws Exception {
+ if (isSSLEnabled()) {
destroySsl();
sslHostConfigs.clear();
final KeyManager keyManager = new KeyManager();
@@ -54,20 +53,22 @@ public class RouterNioEndpoint extends NioEndpoint {
}
}
- synchronized public void replaceSSLHosts(final Map<String,
HandshakeData> sslHostsData){
+ @SuppressWarnings({"PMD.NPathComplexity",
"PMD.UseStringBufferForStringAppends"})
+ synchronized public void replaceSSLHosts(final Map<String,
HandshakeData> sslHostsData) {
final Set<String> aliases = sslHostsData.keySet();
String lastHostName = "";
- for (final String alias : aliases){
+ for (final String alias : aliases) {
final SSLHostConfig sslHostConfig = new SSLHostConfig();
final SSLHostConfigCertificate cert = new
SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.RSA);
+
sslHostConfig.setHostName(sslHostsData.get(alias).getHostname());
cert.setCertificateKeyAlias(alias);
sslHostConfig.addCertificate(cert);
sslHostConfig.setCertificateKeyAlias(alias);
-
sslHostConfig.setHostName(sslHostsData.get(alias).getHostname());
sslHostConfig.setProtocols("all");
+ sslHostConfig.setConfigType(getSslConfigType());
sslHostConfig.setCertificateVerification("none");
- LOGGER.info("sslHostConfig: " +
sslHostConfig.getHostName() + " " + sslHostConfig.getTruststoreAlgorithm());
+ LOGGER.info("sslHostConfig:
"+sslHostConfig.getHostName() + " " + sslHostConfig.getTruststoreAlgorithm());
if (!sslHostConfig.getHostName().equals(lastHostName)){
addSslHostConfig(sslHostConfig, true);
diff --git
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
index e098418..1452585 100644
---
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
+++
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
@@ -17,6 +17,7 @@ package com.comcast.cdn.traffic_control.traffic_router.secure;
import
com.comcast.cdn.traffic_control.traffic_router.protocol.RouterNioEndpoint;
import com.comcast.cdn.traffic_control.traffic_router.shared.CertificateData;
+import com.comcast.cdn.traffic_control.traffic_router.utils.HttpsProperties;
import org.apache.log4j.Logger;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.util.ObjectIdentifier;
@@ -25,7 +26,16 @@ import sun.security.x509.CertificateExtensions;
import sun.security.x509.ExtendedKeyUsageExtension;
import sun.security.x509.KeyUsageExtension;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.security.KeyStore;
import java.security.PrivateKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
@@ -33,7 +43,6 @@ import java.util.Map;
import java.util.Vector;
import sun.security.x509.X500Name;
-import java.security.cert.X509Certificate;
import java.util.Date;
public class CertificateRegistry {
@@ -43,10 +52,16 @@ public class CertificateRegistry {
volatile private Map<String, HandshakeData> handshakeDataMap = new
HashMap<>();
private RouterNioEndpoint sslEndpoint = null;
final private Map<String, CertificateData> previousData = new
HashMap<>();
+ public String defaultAlias;
// Recommended Singleton Pattern implementation
// https://community.oracle.com/docs/DOC-918906
private CertificateRegistry() {
+ try {
+ defaultAlias = InetAddress.getLocalHost().getHostName();
+ } catch (Exception e) {
+ log.error("Error getting hostname");
+ }
}
public static CertificateRegistry getInstance() {
@@ -97,13 +112,49 @@ public class CertificateRegistry {
}
public Map<String, HandshakeData> getHandshakeData() {
- return handshakeDataMap;
- }
+ return handshakeDataMap;
+ }
public void setEndPoint(final RouterNioEndpoint routerNioEndpoint) {
sslEndpoint = routerNioEndpoint;
}
+ private HandshakeData createApiDefaultSsl() {
+ try {
+ final Map<String, String> httpsProperties = (new
HttpsProperties()).getHttpsPropertiesMap();
+
+ final KeyStore ks = KeyStore.getInstance("JKS");
+ final String selfSignedKeystoreFile =
httpsProperties.get("https.certificate.location");
+ if (new File(selfSignedKeystoreFile).exists()) {
+ final String password =
httpsProperties.get("https.password");
+ final InputStream readStream = new
FileInputStream(selfSignedKeystoreFile);
+ ks.load(readStream, password.toCharArray());
+ readStream.close();
+ final Certificate[] certs =
ks.getCertificateChain(defaultAlias);
+ final List<X509Certificate> x509certs = new
ArrayList<>();
+
+ for (final Certificate cert : certs) {
+ final CertificateFactory cf =
CertificateFactory.getInstance("X.509");
+ final ByteArrayInputStream bais = new
ByteArrayInputStream(cert.getEncoded());
+ final X509Certificate x509cert =
(X509Certificate) cf.generateCertificate(bais);
+ x509certs.add(x509cert);
+ }
+
+ X509Certificate[] x509CertsArray = new
X509Certificate[x509certs.size()];
+ x509CertsArray =
x509certs.toArray(x509CertsArray);
+
+ final HandshakeData handshakeData = new
HandshakeData(defaultAlias, defaultAlias,
+ x509CertsArray, (PrivateKey)
ks.getKey(defaultAlias, password.toCharArray()));
+
+ return handshakeData;
+ }
+ } catch (Exception e) {
+ log.error("Failed to load default certificate. Received
" + e.getClass() + " with message: " + e.getMessage());
+ return null;
+ }
+ return null;
+ }
+
@SuppressWarnings("PMD.AccessorClassGeneration")
private static class CertificateRegistryHolder {
private static final CertificateRegistry
DELIVERY_SERVICE_CERTIFICATES = new CertificateRegistry();
@@ -137,13 +188,11 @@ public class CertificateRegistry {
}
}
// find CertificateData which has been removed
- for (final String alias : previousData.keySet())
- {
- if (!master.containsKey(alias) && sslEndpoint != null)
- {
+ for (final String alias : previousData.keySet()) {
+ if (!master.containsKey(alias) && sslEndpoint != null) {
final String hostname =
previousData.get(alias).getHostname();
sslEndpoint.removeSslHostConfig(hostname);
- log.warn("Removed handshake data with hostname " +
hostname);
+ log.warn("Removed handshake data with hostname
" + hostname);
}
}
@@ -166,12 +215,25 @@ public class CertificateRegistry {
final HandshakeData defaultHd =
createDefaultSsl();
if (defaultHd == null){
log.error("Failed to initialize the
CertificateRegistry because of a problem with the 'default' " +
- "certificate.
Returning the Certificate Registry without a default.");
+ "certificate. Returning
the Certificate Registry without a default.");
return;
}
master.put(DEFAULT_SSL_KEY, defaultHd);
}
}
+
+ if (!master.containsKey(defaultAlias)) {
+ if (handshakeDataMap.containsKey(defaultAlias)) {
+ master.put(defaultAlias,
handshakeDataMap.get(defaultAlias));
+ } else {
+ final HandshakeData apiDefault =
createApiDefaultSsl();
+ if (apiDefault == null) {
+ log.error("Failed to initialize the API
Default certificate.");
+ } else {
+ master.put(apiDefault.getHostname(),
apiDefault);
+ }
+ }
+ }
handshakeDataMap = master;
if (sslEndpoint != null) {
diff --git
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/utils/HttpsProperties.java
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/utils/HttpsProperties.java
new file mode 100644
index 0000000..259da8f
--- /dev/null
+++
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/utils/HttpsProperties.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.comcast.cdn.traffic_control.traffic_router.utils;
+
+import org.apache.log4j.Logger;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+public class HttpsProperties {
+ private static final Logger log = Logger.getLogger(HttpsProperties.class);
+ private static final String HTTPS_PROPERTIES_FILE =
"/opt/traffic_router/conf/https.properties";
+ private final Map<String, String> httpsPropertiesMap;
+
+ public HttpsProperties() {
+ this.httpsPropertiesMap = loadHttpsProperties();
+ }
+
+ public Map<String, String> getHttpsPropertiesMap() {
+ return httpsPropertiesMap;
+ }
+
+ private static Map<String, String> loadHttpsProperties() {
+ try {
+ final Map<String, String> httpsProperties = new HashMap<>();
+
Files.readAllLines(Paths.get(HTTPS_PROPERTIES_FILE)).forEach(propString -> {
+ if (!propString.startsWith("#")) { // Ignores comments in
properties file
+ final String[] prop = propString.split("=");
+ httpsProperties.put(prop[0], prop[1]);
+ }
+ });
+ return httpsProperties;
+ } catch (Exception e) {
+ log.error("Error loading https properties file.");
+ return null;
+ }
+ }
+}
diff --git a/traffic_router/core/src/main/conf/https.properties
b/traffic_router/core/src/main/conf/https.properties
new file mode 100644
index 0000000..e5c1791
--- /dev/null
+++ b/traffic_router/core/src/main/conf/https.properties
@@ -0,0 +1,16 @@
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+https.certificate.location=/opt/traffic_router/conf/keyStore.jks
+https.password=changeit
\ No newline at end of file
diff --git a/traffic_router/core/src/main/conf/server.xml
b/traffic_router/core/src/main/conf/server.xml
index 7aeea6b..49750fb 100644
--- a/traffic_router/core/src/main/conf/server.xml
+++ b/traffic_router/core/src/main/conf/server.xml
@@ -39,6 +39,10 @@
sendReasonPhrase="true"/>
<Connector port="3333"
protocol="com.comcast.cdn.traffic_control.traffic_router.protocol.LanguidNioProtocol"
maxThreads="10000"
connectionTimeout="10000"
mbeanPath="traffic-router:name=languidState" readyAttribute="Ready"
portAttribute="ApiPort"/>
+ <Connector port="3443"
protocol="com.comcast.cdn.traffic_control.traffic_router.protocol.LanguidNioProtocol"
maxThreads="10000"
+ scheme="https" secure="true"
SSLEnabled="true" clientAuth="false" sslProtocol="TLS" connectionTimeout="10000"
+ mbeanPath="traffic-router:name=languidState"
readyAttribute="Ready" portAttribute="SecureApiPort" sendReasonPhrase="true"
+
sslImplementationName="com.comcast.cdn.traffic_control.traffic_router.protocol.RouterSslImplementation">
</Connector>
<Connector port="443"
protocol="com.comcast.cdn.traffic_control.traffic_router.protocol.LanguidNioProtocol"
maxThreads="10000"
scheme="https" secure="true"
SSLEnabled="true" clientAuth="false" sslProtocol="TLS" connectionTimeout="10000"
mbeanPath="traffic-router:name=languidState"
readyAttribute="Ready" portAttribute="SecurePort" sendReasonPhrase="true"
diff --git
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/http/RouterFilter.java
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/http/RouterFilter.java
index d683c95..74d713c 100644
---
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/http/RouterFilter.java
+++
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/http/RouterFilter.java
@@ -56,7 +56,7 @@ public class RouterFilter extends OncePerRequestFilter {
public void doFilterInternal(final HttpServletRequest request, final
HttpServletResponse response, final FilterChain chain) throws IOException,
ServletException {
final Date requestDate = new Date();
- if (request.getLocalPort() ==
trafficRouterManager.getApiPort()) {
+ if (request.getLocalPort() == trafficRouterManager.getApiPort()
|| request.getLocalPort() == trafficRouterManager.getSecureApiPort()) {
chain.doFilter(request, response);
return;
}
diff --git
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterManager.java
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterManager.java
index 941ba51..163f996 100644
---
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterManager.java
+++
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouterManager.java
@@ -38,6 +38,7 @@ public class TrafficRouterManager implements
ApplicationListener<ContextRefreshe
private static final Logger LOGGER =
Logger.getLogger(TrafficRouterManager.class);
public static final int DEFAULT_API_PORT = 3333;
+ public static final int DEFAULT_SECURE_API_PORT = 0; // Must be set
through server.xml properties
private JsonNode state;
private TrafficRouter trafficRouter;
@@ -52,6 +53,7 @@ public class TrafficRouterManager implements
ApplicationListener<ContextRefreshe
private SteeringRegistry steeringRegistry;
private ApplicationContext applicationContext;
private int apiPort = DEFAULT_API_PORT;
+ private int secureApiPort = DEFAULT_SECURE_API_PORT;
public NameServer getNameServer() {
return nameServer;
@@ -164,4 +166,12 @@ public class TrafficRouterManager implements
ApplicationListener<ContextRefreshe
public int getApiPort() {
return apiPort;
}
+
+ public int getSecureApiPort() {
+ return secureApiPort;
+ }
+
+ public void setSecureApiPort(final int secureApiPort) {
+ this.secureApiPort = secureApiPort;
+ }
}
diff --git
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/util/LanguidState.java
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/util/LanguidState.java
index e229515..6218ddf 100644
---
a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/util/LanguidState.java
+++
b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/util/LanguidState.java
@@ -32,6 +32,7 @@ public class LanguidState {
private int port = 0;
private int apiPort = 0;
private int securePort = 0;
+ private int secureApiPort = 0;
public void init() {
if (trafficRouterManager == null ||
trafficRouterManager.getTrafficRouter() == null) {
@@ -84,6 +85,11 @@ public class LanguidState {
if (routerJson.has("secure.port")) {
setSecurePort(routerJson.get("secure.port").asInt());
}
+
+ if (routerJson.has("secure.api.port")) {
+
setSecureApiPort(routerJson.get("secure.api.port").asInt());
+ trafficRouterManager.setSecureApiPort(secureApiPort);
+ }
}
public boolean isReady() {
@@ -125,4 +131,12 @@ public class LanguidState {
public void setSecurePort(final int securePort) {
this.securePort = securePort;
}
+
+ public int getSecureApiPort() {
+ return secureApiPort;
+ }
+
+ public void setSecureApiPort(final int secureApiPort) {
+ this.secureApiPort = secureApiPort;
+ }
}
diff --git
a/traffic_router/core/src/main/lib/systemd/system/traffic_router.service
b/traffic_router/core/src/main/lib/systemd/system/traffic_router.service
index ffe4dee..2b26ca4 100755
--- a/traffic_router/core/src/main/lib/systemd/system/traffic_router.service
+++ b/traffic_router/core/src/main/lib/systemd/system/traffic_router.service
@@ -25,6 +25,7 @@ Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/traffic_router
Environment=CATALINA_OUT=/opt/tomcat/logs/catalina.log
EnvironmentFile=/opt/traffic_router/conf/startup.properties
+ExecStartPre=/bin/bash /opt/traffic_router/conf/generatingCerts.sh
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
LimitNOFILE=500000
diff --git a/traffic_router/core/src/main/scripts/postinstall.sh
b/traffic_router/core/src/main/scripts/postinstall.sh
index c4c1e33..1c017ec 100644
--- a/traffic_router/core/src/main/scripts/postinstall.sh
+++ b/traffic_router/core/src/main/scripts/postinstall.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,12 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+keytool=$(dirname $(readlink -f $(which java)))/keytool
+cd /opt/traffic_router/conf
if [ -f /opt/traffic_router/conf/*.crt ]; then
- cd /opt/traffic_router/conf
for file in *.crt; do
alias=$(echo $file |sed -e 's/.crt//g' |tr [:upper:] [:lower:])
cacerts=$(/bin/find $(dirname $(readlink -f $(which java)))/..
-name cacerts)
- keytool=$(dirname $(readlink -f $(which java)))/keytool
$keytool -list -alias $alias -keystore $cacerts -storepass
changeit -noprompt > /dev/null
if [ $? -ne 0 ]; then
@@ -27,6 +28,17 @@ if [ -f /opt/traffic_router/conf/*.crt ]; then
fi
+echo -e "
+cd /opt/traffic_router/conf
+
+keytool=\$(dirname \$(readlink -f \$(which java)))/keytool
+
+if [ ! -f /opt/traffic_router/conf/keyStore.jks ]; then \n
+ \$keytool -genkeypair -v -alias \$(hostname -f) -dname \"CN=\$(hostname
-f), OU=APIDefault, O=Apache Traffic Control, L=Denver, ST=Colorado, C=US\"
-keystore \$(pwd)/keyStore.jks -storepass changeit -keyalg RSA -ext
KeyUsage=\"digitalSignature,keyEncipherment,keyCertSign\" -ext
BasicConstraints:\"critical=ca:true\" -storetype JKS -validity 3650
+ \$keytool -exportcert -v -alias \$(hostname -f) -file \$(hostname -f).crt
-keypass changeit -storepass changeit -keystore \$(pwd)/keyStore.jks -rfc
+fi" >> generatingCerts.sh
+chmod 755 generatingCerts.sh
+
echo "Traffic Router installed successfully."
systemctl daemon-reload
diff --git a/traffic_router/core/src/test/conf/https.properties
b/traffic_router/core/src/test/conf/https.properties
new file mode 100644
index 0000000..e5c1791
--- /dev/null
+++ b/traffic_router/core/src/test/conf/https.properties
@@ -0,0 +1,16 @@
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+https.certificate.location=/opt/traffic_router/conf/keyStore.jks
+https.password=changeit
\ No newline at end of file
diff --git
a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/CatalinaTrafficRouter.java
b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/CatalinaTrafficRouter.java
index 112c4c3..8e9eac5 100644
---
a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/CatalinaTrafficRouter.java
+++
b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/CatalinaTrafficRouter.java
@@ -22,7 +22,11 @@ import org.apache.catalina.core.StandardHost;
import org.apache.catalina.core.StandardService;
import org.apache.catalina.startup.Catalina;
import org.springframework.util.SocketUtils;
+
+import java.util.Arrays;
+import java.util.List;
import java.util.logging.Level;
+import java.util.stream.Collectors;
public class CatalinaTrafficRouter {
Catalina catalina;
@@ -46,6 +50,11 @@ public class CatalinaTrafficRouter {
// Override the port and app base property of server.xml
StandardService trafficRouterService = (StandardService)
catalina.getServer().findService("traffic_router_core");
+ List<Connector> secureConnectorList =
Arrays.stream(trafficRouterService.findConnectors()).filter(k ->
k.getAttribute("portAttribute").equals("SecureApiPort")).collect(Collectors.toList());
+ boolean hasHttpsPort = secureConnectorList.size() > 0;
+ int securePort = hasHttpsPort ?
secureConnectorList.get(0).getPort() : 0;
+ int apiPort =
Arrays.stream(trafficRouterService.findConnectors()).filter(k ->
k.getAttribute("portAttribute").equals("ApiPort")).collect(Collectors.toList()).get(0).getPort();
+
Connector[] connectors = trafficRouterService.findConnectors();
for (Connector connector : connectors) {
if (connector.getPort() == 80) {
@@ -57,6 +66,10 @@ public class CatalinaTrafficRouter {
if (connector.getPort() == 443) {
connector.setPort(Integer.parseInt(System.getProperty("routerSecurePort",
"8443")));
}
+
+ if (connector.getPort() == 3443) {
+
connector.setPort(Integer.parseInt(System.getProperty("secureApiPort",
"3443")));
+ }
System.out.println("[" + System.currentTimeMillis() +
"] >>>>>>>>>>>>>>>> Traffic Router listening on port " + connector.getPort() +
" " + connector.getScheme());
}