Add support for WebProxy with SSL

Add support to disable WebProxy protection for SOLR REST API
This commit is contained in:
Angel Borroy
2019-10-07 16:31:55 +02:00
parent adfb5f661e
commit 4493c6729b
13 changed files with 319 additions and 60 deletions

View File

@@ -1,12 +1,7 @@
# generator-alfresco-docker-compose
> Alfresco Docker Compose Generator
This project generates a collection of Docker Compose Templates to test Repository and Search Services/Insight Engine with different configurations:
* Plain HTTP communications
* TLS/SSL Mutual Authentication communications
* Sharding (dynamic) with different Sharding Methods
* Replication (master/slave)
This project generates a collection of Docker Compose Templates to test Repository and Search Services/Insight Engine with different configurations.
## Project structure
@@ -14,7 +9,6 @@ Following templates are provided.
```
$ tree generators/app/templates/
generators/app/templates/
├── 6.1
│   ├── .env
│   ├── docker-compose-ce.yml
@@ -30,6 +24,13 @@ generators/app/templates/
│   │   ├── empty
│   │   ├── sharding-content-model-context.xml
│   │   └── sharding-content-model.xml
│   ├── config
│   │   ├── cert
│   │   │   ├── localhost.cer
│   │   │   └── localhost.key
│   │   └── nginx
│   │   ├── nginx.conf
│   │   └── nginx.htpasswd
│   ├── search
│   │   └── Dockerfile
│   ├── share
@@ -54,6 +55,7 @@ generators/app/templates/
* `share` includes a Dockerfile template to start Share Web Application
* `model` includes a default forms model (Sharding Explicit Routing or empty)
* `search` includes a Dockerfile template to start Search Services and Insight Engine
* `config` includes configuration for HTTP Web Proxy (NGINX)
* `zeppelin` includes a Dockerfile template to start Zeppelin with SSL
* `keystores` includes every truststore and keystore required for SSL configuration
@@ -99,13 +101,17 @@ If you chose ACS 6.1, a prompt will allow you to use AGS.
When using Community, some different options can be combined:
* Plain HTTP (http) or TLS/SSL Mutual Authentication (https)
* Plain HTTP (http) or TLS/SSL Mutual Authentication (https) for communication between Alfresco and SOLR
* Plain HTTP (http) or HTTPs (https) for Http Web Proxy for HTTP access to services
* Protect the access to SOLR REST API in the Http WebProxy to forbid direct access to Alfresco Web Proxy port
* Use SOLR Replication in Master/Slave mode (only when using http)
```
? Would you like to use Alfresco enterprise or community? community
? Would you like to use http or https? http
? Would you like to use a SOLR Replication (2 nodes in master-slave)? Yes
? Would you like to use HTTP or mTLS for Alfresco-SOLR communication? http
? Would you like to use HTTP or HTTPs for Web Proxy? http
? Would you like to protect the access to SOLR REST API? Yes
? Would you like to use a SOLR Replication (2 nodes in master-slave)? No
```
## Enterprise
@@ -172,22 +178,6 @@ Sample configuration is available in [images/share/model/sharding-share-config-c
If *Sharding* is selected, a default `share-config-custom-dev.xml` file with required forms configuration for Sharding custom model will be available in deployment folder. Add your configuration to this file.
## Configuration catalog
| Version | Comms | Replication | Sharding | Insight | Zeppelin |
| - | - | - | - | - | - |
| community | http | - | x | x | x |
| community | http | true | x | x | x |
| community | https | x | x | x | x |
| enterprise | http | - | - | (*) | (*) |
| enterprise | http | true | false | (*) | (*) |
| enterprise | http | false | true | (*) | (*) |
| enterprise | https | x | - | (*) | (*) |
| enterprise | https | x | true | (*) | (*) |
| enterprise | https | x | true | (*) | (*) |
Both `community` and `enterprise` ACS deployments can be used with the same options, but `enterprise` may also use Insight Engine (replacing Search Services) and Insight Zeppelin services.
## Passing parameters from command line
Default values for options can be specified in the command line, using a `--name=value` pattern. When an options is specified in the command line, the question is not prompted to the user, so you can generate a Docker Compose template with no user interaction.
@@ -202,6 +192,8 @@ $ yo alfresco-docker-compose --acsVersion=6.2 --alfrescoVersion=community --http
`--ags:`: only available when acsVersion=6.1
`--alfrescoVersion`: community or enterprise
`--httpMode`: http or https
`--httpWebMode`: http or https
`--protectSolr`: true or false
`--clustering`: true or false
`--insightEngine`: true or false
`--zeppelin`: true or false
@@ -224,20 +216,24 @@ $ docker-compose down
**Community URLs**
*HTTP*
*WebProxy HTTP and Alfresco-SOLR HTTP*
http://localhost:8080/share
http://localhost:8080/alfresco
http://localhost:8080/solr (with HTTP basic auth)
http://localhost:8083/solr
http://localhost:8080/
When using SOLR Replication, additionally
http://localhost:8084/solr
*SSL*
*WebProxy HTTP and Alfresco-SOLR mTLS*
http://localhost:8080/share
@@ -247,25 +243,57 @@ https://localhost:8443/alfresco
https://localhost:8083/solr
http://localhost:8080/
*WebProxy HTTPs and Alfresco-SOLR HTTP*
https://localhost/share
https://localhost/alfresco
https://localhost/solr (with HTTP basic auth)
https://localhost/
When using SOLR Replication, additionally
http://localhost:8084/solr
*WebProxy HTTPs and Alfresco-SOLR mTLS*
https://localhost/share
https://localhost/alfresco
https://localhost:8083/solr
https://localhost/
**Enterprise URLs**
*HTTP*
*WebProxy HTTP and Alfresco-SOLR HTTP*
http://localhost:8080/share
http://localhost:8080/alfresco
http://localhost:8080/solr (with HTTP basic auth)
http://localhost:8083/solr
http://localhost:9090/zeppelin
http://localhost:8080/
When using SOLR Replication or Sharding, additionally
http://localhost:8084/solr
*SSL*
*WebProxy HTTP and Alfresco-SOLR mTLS*
http://localhost:8080/share
@@ -277,6 +305,34 @@ https://localhost:8083/solr
http://localhost:9090/zeppelin
When using SOLR Sharding, additionally
http://localhost:8080/
https://localhost:8084/solr
*WebProxy HTTPs and Alfresco-SOLR HTTP*
https://localhost/share
https://localhost/alfresco
https://localhost/solr (with HTTP basic auth)
http://localhost:9090/zeppelin
https://localhost/
When using SOLR Replication, additionally
http://localhost:8084/solr
*WebProxy HTTPs and Alfresco-SOLR mTLS*
https://localhost/share
https://localhost/alfresco
https://localhost:8083/solr
http://localhost:9090/zeppelin
https://localhost/

View File

@@ -4,12 +4,8 @@ var banner = require('./banner')
/**
* This module buids a Docker Compose template to test
* Repository and Search Services/Insight Engine in
* different configurations:
* - Plain HTTP communications
* - TLS/SSL Mutual Authentication communications
* - Sharding (dynamic)
* - Replication (master-slave)
* Repository and Search Services/Insight Engine with
* different configurations.
*/
module.exports = class extends Generator {
@@ -45,10 +41,23 @@ module.exports = class extends Generator {
{
type: 'list',
name: 'httpMode',
message: 'Would you like to use http or https?',
message: 'Would you like to use HTTP or mTLS for Alfresco-SOLR communication?',
choices: [ "http", "https" ],
default: 'http'
},
{
type: 'list',
name: 'httpWebMode',
message: 'Would you like to use HTTP or HTTPs for Web Proxy?',
choices: [ "http", "https" ],
default: 'http'
},
{
type: 'confirm',
name: 'protectSolr',
message: 'Would you like to protect the access to SOLR REST API?',
default: 'true'
},
{
whenFunction: response => response.httpMode == 'http',
type: 'confirm',
@@ -186,6 +195,8 @@ module.exports = class extends Generator {
this.destinationPath('docker-compose.yml'),
{
httpMode: this.props.httpMode,
httpWebMode: this.props.httpWebMode,
port: (this.props.httpWebMode == 'http' ? '8080' : '443'),
secureComms: (this.props.httpMode == 'http' ? 'none' : 'https'),
alfrescoPort: (this.props.httpMode == 'http' ? '8080' : '8443'),
replication: (this.props.replication ? "true" : "false"),
@@ -226,7 +237,9 @@ module.exports = class extends Generator {
this.templatePath(imagesDirectory + '/share/Dockerfile'),
this.destinationPath('share/Dockerfile'),
{
shareImage: shareImageName
shareImage: shareImageName,
httpWebMode: this.props.httpWebMode,
port: (this.props.httpWebMode == 'http' ? '8080' : '443'),
}
);
// Copy Sharding Content Forms or an empty file to allow forms deployments
@@ -282,6 +295,24 @@ module.exports = class extends Generator {
}
}
// Copy NGINX Configuration
this.fs.copyTpl(
this.templatePath(imagesDirectory + '/config/nginx'),
this.destinationPath('config'),
{
port: (this.props.httpWebMode == 'http' ? '8080' : '443'),
httpMode: this.props.httpMode,
httpWebMode: this.props.httpWebMode,
protectSolr: (this.props.protectSolr ? 'true' : 'false')
}
);
if (this.props.httpWebMode == 'https') {
this.fs.copy(
this.templatePath(imagesDirectory + '/config/cert'),
this.destinationPath('config/cert')
);
}
}
};

View File

@@ -19,3 +19,4 @@ ACS_NGINX_TAG=3.0.0
ACS_COMMUNITY_NGINX_TAG=1.0.0
SEARCH_TAG=latest
ZEPPELIN_TAG=latest
ACA_TAG=master-latest

View File

@@ -26,8 +26,8 @@ services:
-Dsolr.base.url=/solr
-Dindex.subsystem.name=solr6
-Dshare.host=localhost
-Dalfresco.port=8082
-Daos.baseUrlOverwrite=http://localhost:8082/alfresco/aos
-Dalfresco.port=8080
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
-Dmessaging.broker.url=\"failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true\"
-Ddeployment.method=DOCKER_COMPOSE
-Dcsrf.filter.enabled=false
@@ -159,13 +159,28 @@ services:
- 61616:61616 # OpenWire
- 61613:61613 # STOMP
content-app:
image: alfresco/alfresco-content-app:${ACA_TAG}
mem_limit: 256m
depends_on:
- alfresco
# HTTP proxy to provide HTTP Default port access to services
# SOLR API and SOLR Web Console are protected to avoid unauthenticated access
proxy:
image: alfresco/acs-community-ngnix:${ACS_COMMUNITY_NGINX_TAG}
image: nginx:stable-alpine
mem_limit: 128m
depends_on:
- alfresco
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/nginx.htpasswd:/etc/nginx/conf.d/nginx.htpasswd <% if (httpWebMode == 'https') { %>
- ./config/cert/localhost.cer:/etc/nginx/localhost.cer
- ./config/cert/localhost.key:/etc/nginx/localhost.key <% } %>
ports:
- 8080:8080
- <%=port%>:<%=port%>
links:
- alfresco
- share
- share
- solr6
- content-app

View File

@@ -301,24 +301,31 @@ services:
- 61616:61616 # OpenWire
- 61613:61613 # STOMP
digital-workspace:
content-app:
image: quay.io/alfresco/alfresco-digital-workspace:${DIGITAL_WORKSPACE_TAG}
mem_limit: 128m
environment:
BASEPATH: ./
# HTTP proxy to provide HTTP Default port access to services
# SOLR API and SOLR Web Console are protected to avoid unauthenticated access
proxy:
image: alfresco/alfresco-acs-nginx:${ACS_NGINX_TAG}
image: nginx:stable-alpine
mem_limit: 128m
depends_on:
- alfresco
- digital-workspace
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/nginx.htpasswd:/etc/nginx/conf.d/nginx.htpasswd <% if (httpWebMode == 'https') { %>
- ./config/cert/localhost.cer:/etc/nginx/localhost.cer
- ./config/cert/localhost.key:/etc/nginx/localhost.key <% } %>
ports:
- 8080:8080
- <%=port%>:<%=port%>
links:
- digital-workspace
- alfresco
- share
- solr6
- content-app
volumes:
shared-file-store-volume:

View File

@@ -14,3 +14,4 @@ ACS_NGINX_TAG=3.0.1
ACS_COMMUNITY_NGINX_TAG=1.0.0
SEARCH_TAG=latest
ZEPPELIN_TAG=latest
ACA_TAG=master-latest

View File

@@ -26,8 +26,8 @@ services:
-Dsolr.base.url=/solr
-Dindex.subsystem.name=solr6
-Dshare.host=localhost
-Dalfresco.port=8082
-Daos.baseUrlOverwrite=http://localhost:8082/alfresco/aos
-Dalfresco.port=8080
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
-Dmessaging.broker.url=\"failover:(nio://activemq:61616)?timeout=3000&jms.useCompression=true\"
-Ddeployment.method=DOCKER_COMPOSE
@@ -215,13 +215,28 @@ services:
- 61616:61616 # OpenWire
- 61613:61613 # STOMP
content-app:
image: alfresco/alfresco-content-app:${ACA_TAG}
mem_limit: 256m
depends_on:
- alfresco
# HTTP proxy to provide HTTP Default port access to services
# SOLR API and SOLR Web Console are protected to avoid unauthenticated access
proxy:
image: alfresco/acs-community-ngnix:${ACS_COMMUNITY_NGINX_TAG}
image: nginx:stable-alpine
mem_limit: 128m
depends_on:
- alfresco
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/nginx.htpasswd:/etc/nginx/conf.d/nginx.htpasswd <% if (httpWebMode == 'https') { %>
- ./config/cert/localhost.cer:/etc/nginx/localhost.cer
- ./config/cert/localhost.key:/etc/nginx/localhost.key <% } %>
ports:
- 8080:8080
- <%=port%>:<%=port%>
links:
- alfresco
- share
- share
- solr6
- content-app

View File

@@ -324,24 +324,31 @@ services:
- 61616:61616 # OpenWire
- 61613:61613 # STOMP
digital-workspace:
content-app:
image: quay.io/alfresco/alfresco-digital-workspace:${DIGITAL_WORKSPACE_TAG}
mem_limit: 128m
environment:
BASEPATH: ./
# HTTP proxy to provide HTTP Default port access to services
# SOLR API and SOLR Web Console are protected to avoid unauthenticated access
proxy:
image: alfresco/alfresco-acs-nginx:${ACS_NGINX_TAG}
image: nginx:stable-alpine
mem_limit: 128m
depends_on:
- alfresco
- digital-workspace
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/nginx.htpasswd:/etc/nginx/conf.d/nginx.htpasswd <% if (httpWebMode == 'https') { %>
- ./config/cert/localhost.cer:/etc/nginx/localhost.cer
- ./config/cert/localhost.key:/etc/nginx/localhost.key <% } %>
ports:
- 8080:8080
- <%=port%>:<%=port%>
links:
- digital-workspace
- alfresco
- share
- solr6
- content-app
volumes:
shared-file-store-volume:

View File

@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID0TCCAzqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwfzELMAkGA1UEBhMCR0Ix
CzAJBgNVBAgMAlVLMRMwEQYDVQQHDApNYWlkZW5oZWFkMR8wHQYDVQQKDBZBbGZy
ZXNjbyBTb2Z0d2FyZSBMdGQuMRAwDgYDVQQLDAdVbmtub3duMRswGQYDVQQDDBJD
dXN0b20gQWxmcmVzY28gQ0EwHhcNMTkwODMwMTMzNzQ3WhcNMjkwODI3MTMzNzQ3
WjByMQswCQYDVQQGEwJHQjELMAkGA1UECAwCVUsxHzAdBgNVBAoMFkFsZnJlc2Nv
IFNvZnR3YXJlIEx0ZC4xEDAOBgNVBAsMB1Vua25vd24xIzAhBgNVBAMMGkN1c3Rv
bSBBbGZyZXNjbyBSZXBvc2l0b3J5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQChncDS402ZkMx7DBJwDI1Ycs9MMotmqBcJg85GrGfw9Wpxgsxn3m1AuneBWTgN
3P8BYmxdL/uE8pV6KwWlvh3IPB6hv9PxpS9D9uDfaPmZcXKIQXbj440ysPtCKs6d
/czjcVAzoG4oq/XVAS3QPGK5WsqUOmvskES7Y0pkRLwpWQIDAQABo4IBZzCCAWMw
CQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9w
ZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUFz5n
fbUE7IRj4sQ0FKnMwSJdGy8wgbMGA1UdIwSBqzCBqIAUsA46Qj0+T/tpicaxqYYV
/hzfJgKhgYSkgYEwfzELMAkGA1UEBhMCR0IxCzAJBgNVBAgMAlVLMRMwEQYDVQQH
DApNYWlkZW5oZWFkMR8wHQYDVQQKDBZBbGZyZXNjbyBTb2Z0d2FyZSBMdGQuMRAw
DgYDVQQLDAdVbmtub3duMRswGQYDVQQDDBJDdXN0b20gQWxmcmVzY28gQ0GCCQCi
8OUigUs5TTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwFAYD
VR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4GBADWOrvgLnmxA7fqL
RDRVLI+OO5rtXLsnagb+MJBao7NYJsNADdugQ+MegSDLQQXCWb1ynZ6010a7aLP6
KeSRgqJxvfvuMyhWo0mmB9f4h1OhkLBFGVOaI4Jk3RTlzcrDTVUige9OBex7Pjjl
PCpxaGAbXG44RiFhxzNC63Eay6Om
-----END CERTIFICATE-----

View File

@@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKGdwNLjTZmQzHsM
EnAMjVhyz0wyi2aoFwmDzkasZ/D1anGCzGfebUC6d4FZOA3c/wFibF0v+4TylXor
BaW+Hcg8HqG/0/GlL0P24N9o+ZlxcohBduPjjTKw+0Iqzp39zONxUDOgbiir9dUB
LdA8YrlaypQ6a+yQRLtjSmREvClZAgMBAAECgYAYr1m2XFWL8RvqZ2uhhalJKzAS
eV3lbiMmpuUo0kiF+1YoxEuoScbyLgj2zsPLCkhA0+GtUhjes5a1NEEGkcVGhA05
QxUSBMQ+aLu6b6XY4A2XklMaD+ScqqpEN4zAEniNrL4Hbgx9VlPtLl+dpKFoCn9Q
RJYzGvr2CGFK71VhoQJBANH/zszcjqwADA0iW5LrXIBJ/Xd7pQdBwX/DtqGcoUqm
abfCoGqhyE4wCspGff/56D3cZKPQsf9+AO+YGssRrBUCQQDFBMFyx2F+hdWhkdUG
fIBo7+D6GGP4Gjj/hw8YcD6zpVInU3ctuAjumAY0U2X5HzJMXKXY1QjrxLUmOSIG
AqU1AkBomcbkfCgEvLFECY0bjWix7ij2zvvQtYwwm8fokCA3EtUt1yAYfSVM7Nkz
EBHK4ywvRAxNHLLM1HKa5WTTKaZRAkEAw62EgP5b67D7TDyuSoHve8n8NglxiOJq
iAhZStl4vS5OmTaB4Quu+2JMjz3hwvtkFonSQrjb4mb90FfgXf3UnQJAKpW2mb3M
PjJec8f5vT16PNASSi+TiGAjRddMoG6AP4gcSlx3OZGupyJnlPU41nGuOlLDOB1d
gxp42gv4pSjERw==
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,81 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen *:<%=port%><% if (httpWebMode == 'https') { %> ssl<% } %>;
client_max_body_size 0;
set $allowOriginSite *;
proxy_pass_request_headers on;
proxy_pass_header Set-Cookie;
<% if (httpWebMode == 'https') { %>
ssl_certificate /etc/nginx/localhost.cer;
ssl_certificate_key /etc/nginx/localhost.key;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_protocols TLSv1.1 TLSv1.2;
<% } %>
# External settings, do not remove
#ENV_ACCESS_LOG
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Set-Cookie;
<% if (protectSolr == 'https') { %>
# Protect access to SOLR APIs
location ~ ^(/.*/service/api/solr/.*)$ {return 403;}
location ~ ^(/.*/s/api/solr/.*)$ {return 403;}
location ~ ^(/.*/wcservice/api/solr/.*)$ {return 403;}
location ~ ^(/.*/wcs/api/solr/.*)$ {return 403;}
location ~ ^(/.*/proxy/alfresco/api/solr/.*)$ {return 403 ;}
location ~ ^(/.*/-default-/proxy/alfresco/api/.*)$ {return 403;}
<% } %>
# Alfresco Repository
location /alfresco/ {
proxy_pass http://alfresco:8080;
}
# REST API (Swagger)
location /api-explorer/ {
proxy_pass http://alfresco:8080;
}
<% if (httpMode == 'http') { %>
# SOLR Web Console (Master)
location /solr/ {
proxy_pass http://solr6:8983;
# Basic authentication
auth_basic "Solr web console";
auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;
}
<% } %>
# Alfresco Share Web App
location /share/ {
proxy_pass http://share:8080;
}
# Alfresco Content App
location / {
proxy_pass http://content-app:8080;
}
}
}

View File

@@ -3,5 +3,10 @@ FROM <%=shareImage%>:${SHARE_TAG}
ARG TOMCAT_DIR=/usr/local/tomcat
<% if (httpWebMode == 'https') { %>
RUN sed -i '/Connector port="8080"/a scheme="https" secure="true"' /usr/local/tomcat/conf/server.xml && \
sed -i '/Connector port="8080"/a proxyName="localhost" proxyPort="<%=port%>"' /usr/local/tomcat/conf/server.xml
<% } %>
# Copy custom content forms to deployment folder
COPY model/* $TOMCAT_DIR/shared/classes/alfresco/web-extension/