├── README.md
├── etc
├── apache2
│ └── ports.conf
└── nginx
│ └── conf.d
│ ├── proxy.conf
│ └── upstreams.conf
└── usr
└── local
└── ispconfig
└── server
├── conf-custom
├── nginx_reverse_proxy_plugin.vhost.conf.master
└── vhost.conf.master
└── plugins-available
└── nginx_reverse_proxy_plugin.inc.php
/README.md:
--------------------------------------------------------------------------------
1 | Please visit [MixasikM/ispconfig3-nginx-reverse-proxy](https://github.com/MixasikM/ispconfig3-nginx-reverse-proxy) for a fork that seems to be maintaned.
2 |
--------------------------------------------------------------------------------
/etc/apache2/ports.conf:
--------------------------------------------------------------------------------
1 | # If you just change the port or add more ports here, you will likely also
2 | # have to change the VirtualHost statement in
3 | # /etc/apache2/sites-enabled/000-default
4 | # This is also true if you have upgraded from before 2.2.9-3 (i.e. from
5 | # Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and
6 | # README.Debian.gz
7 |
8 | NameVirtualHost *:82
9 | Listen 127.0.0.1:82
10 | Listen ::1:82
11 |
--------------------------------------------------------------------------------
/etc/nginx/conf.d/proxy.conf:
--------------------------------------------------------------------------------
1 | proxy_redirect off;
2 | proxy_buffering on;
3 |
4 | proxy_set_header Host $host;
5 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
6 | proxy_set_header X-Forwarded-Proto $scheme;
7 |
8 | proxy_pass_header Set-Cookie;
9 |
--------------------------------------------------------------------------------
/etc/nginx/conf.d/upstreams.conf:
--------------------------------------------------------------------------------
1 | upstream apache2 {
2 | server [::1]:82 max_fails=3 fail_timeout=10;
3 | }
4 |
--------------------------------------------------------------------------------
/usr/local/ispconfig/server/conf-custom/nginx_reverse_proxy_plugin.vhost.conf.master:
--------------------------------------------------------------------------------
1 |
2 | server {
3 |
4 | ######################################################################
5 | ## Server configuration
6 | ######################################################################
7 |
8 |
9 | listen :443 ssl spdy;
10 | listen [::]:443 ssl spdy;
11 |
12 | listen :80;
13 | listen [::]:80;
14 |
15 |
16 | server_name [];
17 |
18 | root ;
19 |
20 | # recommended but not manditory directives
21 | # leave commented out unless you know what they are doing
22 | #limit_req zone=ddos-cage burst=50;
23 | #proxy_cache nginx_cache;
24 |
25 | ######################################################################
26 | ## Log configuration
27 | ######################################################################
28 |
29 | access_log off;
30 |
31 |
32 | ######################################################################
33 | ## SSL configuration
34 | ######################################################################
35 |
36 | # recommended but not manditory directive
37 | # leave commented out unless you know what it is doing
38 | #more_set_headers 'Strict-Transport-Security: max-age=15768000';
39 |
40 | ssl_certificate /.nginx.crt;
41 | ssl_certificate_key /.key;
42 |
43 |
44 | ######################################################################
45 | ## Redirects configuration
46 | ######################################################################
47 |
48 |
49 | # Redirect http -> https
50 | return 301 https://$server_name$request_uri;
51 |
52 |
53 |
54 | # SEO Redirect
55 | if ($http_host = "") {
56 | return 301 $scheme://$request_uri;
57 | }
58 |
59 |
60 | ######################################################################
61 | ## Locations configuration
62 | ######################################################################
63 |
64 | # global locations
65 | # recommended but not manditory directive
66 | # leave commented out unless you know what it is doing
67 | # include /etc/nginx/locations.d/*.conf;
68 |
69 | # alias to local error docs
70 |
71 | location ^~ /error { root /var/www; }
72 |
73 |
74 | # default location
75 | location / {
76 | proxy_pass http://apache2;
77 | }
78 |
79 | ######################################################################
80 | ## Directives configuration
81 | ######################################################################
82 |
83 |
84 |
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/usr/local/ispconfig/server/conf-custom/vhost.conf.master:
--------------------------------------------------------------------------------
1 |
2 | AllowOverride None
3 |
4 | Require all denied
5 |
6 | Order Deny,Allow
7 | Deny from all
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | # Common
16 | ServerAdmin admin@rackster-server.ch
17 | ServerName
18 |
19 |
20 |
21 |
22 | ServerAlias
23 |
24 |
25 | # Logging
26 | ErrorLog /var/log/ispconfig/httpd//error.log
27 |
28 | # Document root
29 |
30 | DocumentRoot
31 |
32 |
33 | DocumentRoot
34 |
35 |
36 | DocumentRoot
37 |
38 | DocumentRoot
39 |
40 |
41 |
42 |
43 | # Rewrites
44 |
45 | RewriteEngine on
46 |
47 | RewriteCond %{HTTP_HOST} ^$ [NC]
48 | RewriteRule ^(.*)$ https://$1 [R=301,L]
49 |
50 |
51 | RewriteCond %{HTTP_HOST} ^$ [NC]
52 | RewriteRule ^(.*)$ https://$1 [R=301,L]
53 |
54 |
55 | RewriteCond %{HTTP_HOST} $ [NC]
56 |
57 | RewriteCond %{REQUEST_URI} !^/webdav/
58 | RewriteCond %{REQUEST_URI} !^/php5-fcgi/
59 | RewriteCond %{REQUEST_URI} !^
60 |
61 | RewriteRule ^/(.*)$ $1
62 |
63 |
64 |
65 | # Error pages
66 |
67 | Alias /error/ "/error/"
68 |
69 | Alias /error/ /var/www/error/
70 |
71 | Options -Indexes +FollowSymLinks
72 | AllowOverride None
73 |
74 | Require all granted
75 |
76 | Order allow,deny
77 | Allow from all
78 |
79 |
80 |
81 | ErrorDocument 400 /error/400.html
82 | ErrorDocument 401 /error/401.html
83 | ErrorDocument 403 /error/403.html
84 | ErrorDocument 404 /error/404.html
85 | ErrorDocument 405 /error/405.html
86 | ErrorDocument 500 /error/500.html
87 | ErrorDocument 502 /error/502.html
88 | ErrorDocument 503 /error/503.html
89 |
90 |
91 | # Clear PHP settings of this website
92 |
93 | SetHandler None
94 |
95 | Options -Indexes +FollowSymLinks
96 | AllowOverride
97 |
98 | Require all granted
99 |
100 | Order allow,deny
101 | Allow from all
102 |
103 |
104 |
105 | # ssi enabled
106 | AddType text/html .shtml
107 | AddOutputFilter INCLUDES .shtml
108 | Options +Includes
109 |
110 |
111 |
112 |
113 |
114 | Require all denied
115 |
116 | Order allow,deny
117 | Deny from all
118 | Allow from none
119 |
120 |
121 |
122 |
123 |
124 |
125 | # Clear PHP settings of this website
126 |
127 | SetHandler None
128 |
129 | Options -Indexes +FollowSymLinks
130 | AllowOverride
131 |
132 | Require all granted
133 |
134 | Order allow,deny
135 | Allow from all
136 |
137 |
138 |
139 | # ssi enabled
140 | AddType text/html .shtml
141 | AddOutputFilter INCLUDES .shtml
142 | Options +Includes
143 |
144 |
145 |
146 |
147 |
148 | Require all denied
149 |
150 | Order allow,deny
151 | Deny from all
152 | Allow from none
153 |
154 |
155 |
156 |
157 |
158 | # Ruby
159 |
160 |
161 |
162 | Options +ExecCGI
163 |
164 | RubyRequire apache/ruby-run
165 | #RubySafeLevel 0
166 | AddType text/html .rb
167 | AddType text/html .rbx
168 |
169 | SetHandler ruby-object
170 | RubyHandler Apache::RubyRun.instance
171 |
172 |
173 | SetHandler ruby-object
174 | RubyHandler Apache::RubyRun.instance
175 |
176 |
177 |
178 |
179 | # Perl
180 |
181 |
182 | PerlModule ModPerl::Registry
183 | PerlModule Apache2::Reload
184 |
185 | PerlResponseHandler ModPerl::Registry
186 | PerlOptions +ParseHeaders
187 | Options +ExecCGI
188 |
189 |
190 | PerlResponseHandler ModPerl::Registry
191 | PerlOptions +ParseHeaders
192 | Options +ExecCGI
193 |
194 |
195 | SetHandler perl-script
196 |
197 |
198 |
199 |
200 | # Python
201 |
202 |
203 |
204 |
205 | SetHandler mod_python
206 |
207 | PythonHandler mod_python.publisher
208 | PythonDebug On
209 |
210 |
211 |
212 |
213 | # CGI
214 |
215 | # cgi enabled
216 |
217 |
218 | Require all granted
219 |
220 | Order allow,deny
221 | Allow from all
222 |
223 |
224 |
225 | ScriptAlias /cgi-bin/ /cgi-bin/
226 |
227 | SetHandler cgi-script
228 |
229 |
230 |
231 | # SuExec
232 |
233 | # suexec enabled
234 |
235 | SuexecUserGroup
236 |
237 |
238 |
239 | # mod_php
240 |
241 | # mod_php enabled
242 | AddType application/x-httpd-php .php .php3 .php4 .php5
243 | php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -fwebmaster@"
244 | php_admin_value upload_tmp_dir /tmp
245 | php_admin_value session.save_path /tmp
246 | # PHPIniDir
247 |
248 |
249 | php_admin_value open_basedir
250 |
251 |
252 |
253 | # suPHP
254 |
255 | # suphp enabled
256 |
257 |
258 | suPHP_Engine on
259 | # suPHP_UserGroup
260 |
261 |
262 | suPHP_ConfigPath
263 |
264 |
265 |
266 | SetHandler x-httpd-suphp
267 |
268 | suPHP_AddHandler x-httpd-suphp
269 |
270 |
271 |
272 |
273 | # PHP CGI
274 |
275 | # php as cgi enabled
276 | ScriptAlias /php5-cgi
277 | Action php5-cgi /php5-cgi
278 |
279 |
280 | SetHandler php5-cgi
281 |
282 |
283 |
284 |
285 | SetHandler php5-cgi
286 |
287 |
288 |
289 |
290 | Require all granted
291 |
292 | Order allow,deny
293 | Allow from all
294 |
295 |
296 |
297 |
298 | # FastCGI
299 |
300 | # php as fast-cgi enabled
301 | # For config options see: http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html
302 |
303 |
304 | FcgidIdleTimeout 300
305 | FcgidProcessLifeTime 3600
306 | # FcgidMaxProcesses 1000
307 | FcgidMaxRequestsPerProcess
308 | FcgidMinProcessesPerClass 0
309 | FcgidMaxProcessesPerClass 10
310 | FcgidConnectTimeout 3
311 | FcgidIOTimeout 600
312 | FcgidBusyTimeout 3600
313 | FcgidMaxRequestLen 1073741824
314 |
315 | IdleTimeout 300
316 | ProcessLifeTime 3600
317 | # MaxProcessCount 1000
318 | DefaultMinClassProcessCount 0
319 | DefaultMaxClassProcessCount 100
320 | IPCConnectTimeout 3
321 | IPCCommTimeout 360
322 | BusyTimeout 3600
323 |
324 |
325 |
326 |
327 |
328 | SetHandler fcgid-script
329 |
330 | FCGIWrapper .php
331 | FCGIWrapper .php3
332 | FCGIWrapper .php4
333 | FCGIWrapper .php5
334 | Options +ExecCGI
335 | AllowOverride
336 |
337 | Require all granted
338 |
339 | Order allow,deny
340 | Allow from all
341 |
342 |
343 |
344 |
345 |
346 | SetHandler fcgid-script
347 |
348 | FCGIWrapper .php
349 | FCGIWrapper .php3
350 | FCGIWrapper .php4
351 | FCGIWrapper .php5
352 | Options +ExecCGI
353 | AllowOverride
354 |
355 | Require all granted
356 |
357 | Order allow,deny
358 | Allow from all
359 |
360 |
361 |
362 |
363 | # PHP-FPM
364 |
365 |
366 |
367 |
368 | Require all granted
369 |
370 | Order allow,deny
371 | Allow from all
372 |
373 |
374 |
375 |
376 | SetHandler php5-fcgi
377 |
378 |
379 |
380 |
381 | SetHandler php5-fcgi
382 |
383 |
384 | Action php5-fcgi /php5-fcgi
385 | Alias /php5-fcgi {tmpl_var name='document_root'}/cgi-bin/php5-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'}
386 |
387 | FastCgiExternalServer {tmpl_var name='document_root'}/cgi-bin/php5-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'} -idle-timeout 300 -host 127.0.0.1: -pass-header Authorization
388 |
389 | ProxyPassMatch ^/(.*\.php[345]?(/.*)?)$ fcgi://127.0.0.1:/$1
390 |
391 |
392 |
393 | FastCgiExternalServer {tmpl_var name='document_root'}/cgi-bin/php5-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'} -idle-timeout 300 -socket -pass-header Authorization
394 |
395 |
396 |
397 |
398 | # add support for apache mpm_itk
399 |
400 | AssignUserId
401 |
402 |
403 |
404 | # Do not execute PHP files in webdav directory
405 |
406 |
407 | SecRuleRemoveById 960015
408 | SecRuleRemoveById 960032
409 |
410 |
411 | SetHandler None
412 |
413 |
414 |
415 | DavLockDB {tmpl_var name='document_root'}/tmp/DavLock
416 | # DO NOT REMOVE THE COMMENTS!
417 | # IF YOU REMOVE THEM, WEBDAV WILL NOT WORK ANYMORE!
418 | # WEBDAV BEGIN
419 | # WEBDAV END
420 |
421 |
422 |
423 |
424 |
425 |
426 |
--------------------------------------------------------------------------------
/usr/local/ispconfig/server/plugins-available/nginx_reverse_proxy_plugin.inc.php:
--------------------------------------------------------------------------------
1 |
10 | * @link https://open-source.rackster.ch/project/ispconfig3-nginx-reverse-proxy-plugin
11 | */
12 | class nginx_reverse_proxy_plugin {
13 |
14 | /**
15 | * Stores the internal plugin name.
16 | *
17 | * @var string
18 | */
19 | var $plugin_name = 'nginx_reverse_proxy_plugin';
20 |
21 | /**
22 | * Stores the internal class name.
23 | *
24 | * Needs to be the same as $plugin_name.
25 | *
26 | * @var string
27 | */
28 | var $class_name = 'nginx_reverse_proxy_plugin';
29 |
30 | /**
31 | * Stores the current vhost action.
32 | *
33 | * When ISPConfig triggers the vhost event, it passes either create,update,delete etc.
34 | *
35 | * @see onLoad()
36 | *
37 | * @var string
38 | */
39 | var $action = '';
40 |
41 |
42 | /**
43 | * ISPConfig onInstall hook.
44 | *
45 | * Called during ISPConfig installation to determine if a symlink shall be created.
46 | *
47 | * @return bool create symlink if true
48 | */
49 | function onInstall() {
50 | global $conf;
51 | return $conf['services']['web'] == true;
52 | }
53 |
54 | /**
55 | * ISPConfig onLoad hook.
56 | *
57 | * Register the plugin for some site related events.
58 | */
59 | function onLoad() {
60 | global $app;
61 |
62 | $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl');
63 | $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl');
64 | $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl');
65 |
66 | $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert');
67 | $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update');
68 | $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete');
69 |
70 | $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete');
71 | }
72 |
73 |
74 | /**
75 | * ISPConfig ssl hook.
76 | *
77 | * Called every time something in the ssl tab is done.
78 | *
79 | * @see onLoad()
80 | * @uses cert_helper()
81 | *
82 | * @param string $event_name the event/action name
83 | * @param array $data the vhost data
84 | */
85 | function ssl($event_name, $data) {
86 | global $app, $conf;
87 |
88 | $app->uses('system');
89 |
90 | //* Only vhosts can have a ssl cert
91 | if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain") {
92 | return;
93 | }
94 |
95 | if ($data['new']['ssl_action'] == 'del') {
96 | $this->cert_helper('delete', $data);
97 | } else {
98 | $this->cert_helper('update', $data);
99 | }
100 | }
101 |
102 | /**
103 | * ISPConfig insert hook.
104 | *
105 | * Called every time a new site is created.
106 | *
107 | * @uses update()
108 | *
109 | * @param string $event_name the event/action name
110 | * @param array $data the vhost data
111 | */
112 | function insert($event_name, $data) {
113 | global $app, $conf;
114 |
115 | $this->action = 'insert';
116 | $this->update($event_name, $data);
117 | }
118 |
119 | /**
120 | * ISPConfig update hook.
121 | *
122 | * Called every time a site gets updated from within ISPConfig.
123 | *
124 | * @see insert()
125 | * @see delete()
126 | *
127 | * @param string $event_name the event/action name
128 | * @param array $data the vhost data
129 | */
130 | function update($event_name, $data) {
131 | global $app, $conf;
132 |
133 | //* $VAR: command to run after vhost insert/update/delete
134 | $final_command = '/etc/init.d/nginx reload';
135 |
136 | if ($this->action != 'insert') {
137 | $this->action = 'update';
138 | }
139 |
140 | $app->uses('getconf');
141 | $app->uses('system');
142 | $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
143 |
144 | $app->load('tpl');
145 |
146 | $tpl = new tpl();
147 | $tpl->newTemplate('nginx_reverse_proxy_plugin.vhost.conf.master');
148 |
149 | $web_folder = 'web';
150 | if($data['new']['type'] == 'vhostsubdomain') {
151 | $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['new']['parent_domain_id']));
152 | $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
153 |
154 | if($subdomain_host == '') {
155 | $subdomain_host = 'web'.$data['new']['domain_id'];
156 | }
157 |
158 | $web_folder = $data['new']['web_folder'];
159 | unset($tmp);
160 | }
161 |
162 | $vhost_data = $data['new'];
163 | $vhost_data['web_document_root'] = $data['new']['document_root'].'/'.$web_folder;
164 | $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/'.$web_folder;
165 | $vhost_data['web_basedir'] = $web_config['website_basedir'];
166 | $vhost_data['ssl_domain'] = $data['new']['ssl_domain'];
167 |
168 | /* __ VHOST & VHOSTSUBDOMAIN - section for vhosts and vhostsubdomains //////////////*/
169 | if ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') {
170 | if ($data['new']['ipv6_address'] != '') {
171 | $tpl->setVar('ipv6_enabled', 1);
172 | }
173 |
174 | $server_alias = array();
175 | switch($data['new']['subdomain']) {
176 | case 'www':
177 | // if seo-redirect is enabled, this should be placed in separate server block
178 | // to prevent if statement in server/request!
179 | $server_alias[] .= 'www.'. $data['new']['domain'] .' ';
180 | break;
181 | case '*':
182 | $server_alias[] .= '*.'. $data['new']['domain'] .' ';
183 | break;
184 | }
185 |
186 | $alias_result = array();
187 | $alias_result = $app->dbmaster->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y' AND type != 'vhostsubdomain'");
188 |
189 | if (count($alias_result) > 0) {
190 | // if alias is redirect type, put in server block with seo-redirect to prevent
191 | // if statement in server/request!
192 | foreach($alias_result as $alias) {
193 | switch($alias['subdomain']) {
194 | case 'www':
195 | $server_alias[] .= 'www.'. $alias['domain'] .' '. $alias['domain'] .' ';
196 | break;
197 | case '*':
198 | $server_alias[] .= '*.'. $alias['domain'] .' '. $alias['domain'] .' ';
199 | break;
200 | default:
201 | $server_alias[] .= $alias['domain'] .' ';
202 | }
203 |
204 | $app->log('Add server alias: '. $alias['domain'], LOGLEVEL_DEBUG);
205 | }
206 |
207 | unset($alias);
208 | }
209 |
210 | if (count($server_alias) > 0) {
211 | $server_alias_str = '';
212 |
213 | foreach($server_alias as $tmp_alias) {
214 | $server_alias_str .= $tmp_alias;
215 | }
216 |
217 | unset($tmp_alias);
218 | $tpl->setVar('alias', $server_alias_str);
219 | } else {
220 | $tpl->setVar('alias', '');
221 | }
222 |
223 | if (!isset($rewrite_rules)) {
224 | $rewrite_rules = array();
225 | }
226 |
227 | if ($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
228 | if (substr($data['new']['redirect_path'], -1) != '/') {
229 | $data['new']['redirect_path'] .= '/';
230 | }
231 |
232 | if (substr($data['new']['redirect_path'], 0, 8) == '[scheme]') {
233 | $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8);
234 | $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8);
235 | } else {
236 | $rewrite_target = $data['new']['redirect_path'];
237 | $rewrite_target_ssl = $data['new']['redirect_path'];
238 | }
239 |
240 | if (substr($data['new']['redirect_path'], 0, 4) == 'http') {
241 | $data['new']['redirect_type'] = 'permanent';
242 | } else {
243 | switch($data['new']['redirect_type']) {
244 | case 'no':
245 | $data['new']['redirect_type'] = 'break';
246 | break;
247 | case 'L':
248 | $data['new']['redirect_type'] = 'break';
249 | break;
250 | default:
251 | $data['new']['redirect_type'] = 'permanent';
252 | }
253 | }
254 |
255 | switch($data['new']['subdomain']) {
256 | case 'www':
257 | $rewrite_rules[] = array(
258 | 'rewrite_domain' => '^'.$data['new']['domain'],
259 | 'rewrite_type' => ($data['new']['redirect_type'] == 'no') ? '' : $data['new']['redirect_type'],
260 | 'rewrite_target' => $rewrite_target,
261 | 'rewrite_target_ssl' => $rewrite_target_ssl
262 | );
263 | $rewrite_rules[] = array(
264 | 'rewrite_domain' => '^www.'.$data['new']['domain'],
265 | 'rewrite_type' => ($data['new']['redirect_type'] == 'no') ? '' : $data['new']['redirect_type'],
266 | 'rewrite_target' => $rewrite_target,
267 | 'rewrite_target_ssl' => $rewrite_target_ssl
268 | );
269 | break;
270 | case '*':
271 | $rewrite_rules[] = array(
272 | 'rewrite_domain' => '(^|\.)'.$data['new']['domain'],
273 | 'rewrite_type' => ($data['new']['redirect_type'] == 'no') ? '' : $data['new']['redirect_type'],
274 | 'rewrite_target' => $rewrite_target,
275 | 'rewrite_target_ssl' => $rewrite_target_ssl
276 | );
277 | break;
278 | default:
279 | $rewrite_rules[] = array(
280 | 'rewrite_domain' => '^'.$data['new']['domain'],
281 | 'rewrite_type' => ($data['new']['redirect_type'] == 'no') ? '' : $data['new']['redirect_type'],
282 | 'rewrite_target' => $rewrite_target,
283 | 'rewrite_target_ssl' => $rewrite_target_ssl
284 | );
285 | }
286 | }
287 |
288 | if ($data['new']['seo_redirect'] != '' && ($data['new']['subdomain'] == 'www' || $data['new']['subdomain'] == '*')) {
289 | $vhost_data['seo_redirect_enabled'] = 1;
290 |
291 | if ($data['new']['seo_redirect'] == 'non_www_to_www') {
292 | $vhost_data['seo_redirect_origin_domain'] = $data['new']['domain'];
293 | $vhost_data['seo_redirect_target_domain'] = 'www.'. $data['new']['domain'];
294 | }
295 |
296 | if ($data['new']['seo_redirect'] == 'www_to_non_www') {
297 | $vhost_data['seo_redirect_origin_domain'] = 'www.'. $data['new']['domain'];
298 | $vhost_data['seo_redirect_target_domain'] = $data['new']['domain'];
299 | }
300 | } else {
301 | $vhost_data['seo_redirect_enabled'] = 0;
302 | }
303 |
304 | $errordocs = !$data['new']['errordocs'];
305 |
306 | $nginx_directives = $data['new']['nginx_directives'];
307 | $nginx_directives = str_replace("\r\n", "\n", $nginx_directives);
308 | $nginx_directives = str_replace("\r", "\n", $nginx_directives);
309 |
310 | $crt_file = escapeshellcmd($data['new']['document_root'] .'/ssl/'. $data['new']['ssl_domain'] .'.crt');
311 | $key_file = escapeshellcmd($data['new']['document_root'] .'/ssl/'. $data['new']['ssl_domain'] .'.key');
312 |
313 | if ($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && is_file($crt_file) && is_file($key_file) && (filesize($crt_file) > 0) && (filesize($key_file) > 0)) {
314 | $http_to_https = 1;
315 | } else {
316 | $http_to_https = 0;
317 | }
318 |
319 | // non-ssl vhost loop
320 | if (count($rewrite_rules) > 0) {
321 | $vhosts[] = array(
322 | 'ip_address' => $data['new']['ip_address'],
323 | 'ipv6_address' => $data['new']['ipv6_address'],
324 | 'ssl_enabled' => 0,
325 | 'http_to_https' => $http_to_https,
326 | 'nginx_directives' => $nginx_directives,
327 | 'errordocs' => $errordocs,
328 | 'port' => 80
329 | );
330 | } else {
331 | $vhosts[] = array(
332 | 'ip_address' => $data['new']['ip_address'],
333 | 'ipv6_address' => $data['new']['ipv6_address'],
334 | 'ssl_enabled' => 0,
335 | 'http_to_https' => $http_to_https,
336 | 'nginx_directives' => $nginx_directives,
337 | 'errordocs' => $errordocs,
338 | 'port' => 80
339 | );
340 | }
341 |
342 | // ssl vhost loop
343 | if ($http_to_https == 1) {
344 | $vhost_data['web_document_root_ssl'] = $data['new']['document_root'] .'/ssl';
345 |
346 | if (count($rewrite_rules) > 0) {
347 | $vhosts[] = array(
348 | 'ip_address' => $data['new']['ip_address'],
349 | 'ipv6_address' => $data['new']['ipv6_address'],
350 | 'ssl_enabled' => 1,
351 | 'http_to_https' => 0,
352 | 'rewrite_enabled' => 1,
353 | 'nginx_directives' => $nginx_directives,
354 | 'errordocs' => $errordocs,
355 | 'port' => 443
356 | );
357 | } else {
358 | $vhosts[] = array(
359 | 'ip_address' => $data['new']['ip_address'],
360 | 'ipv6_address' => $data['new']['ipv6_address'],
361 | 'ssl_enabled' => 1,
362 | 'http_to_https' => 0,
363 | 'rewrite_enabled' => 0,
364 | 'nginx_directives' => $nginx_directives,
365 | 'errordocs' => $errordocs,
366 | 'port' => 443
367 | );
368 | }
369 | }
370 |
371 | $tpl->setLoop('vhosts', $vhosts);
372 | $tpl->setVar($vhost_data);
373 |
374 | if ($this->action == 'insert') {
375 | $this->vhost_helper('insert', $data, $tpl->grab());
376 | }
377 |
378 | if ($this->action == 'update') {
379 | $vhost_backup = $this->vhost_helper('update', $data, $tpl->grab());
380 | }
381 | }
382 |
383 |
384 | /**
385 | * Section for aliasdomains.
386 | *
387 | * This section is used for aliasdomains.
388 | */
389 | if ($data['new']['type'] == 'alias') {
390 | $parent_domain = $app->dbmaster->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '. intval($data['new']['parent_domain_id']) .'');
391 |
392 | $parent_domain['parent_domain_id'] = $data['new']['parent_domain_id'];
393 | $data['old'] = $parent_domain;
394 | $data['new'] = $parent_domain;
395 |
396 | $this->update($event_name, $data);
397 | }
398 |
399 | /**
400 | * Section for classic subdomains.
401 | *
402 | * This section is used for classic subdomains (non vhost subdomains).
403 | */
404 | if ($data['new']['type'] == 'subdomain') {
405 | $parent_domain = $app->dbmaster->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '. intval($data['new']['parent_domain_id']) .'');
406 |
407 | $parent_domain['parent_domain_id'] = $data['new']['parent_domain_id'];
408 | $data['old'] = $parent_domain;
409 | $data['new'] = $parent_domain;
410 |
411 | $this->update($event_name, $data);
412 | }
413 |
414 | exec($final_command);
415 |
416 | if (isset($vhost_backup)) {
417 | $app->system->unlink($vhost_backup['file_new'].'~');
418 | }
419 |
420 | unset($vhost_backup);
421 | $this->action = '';
422 | }
423 |
424 | /**
425 | * ISPConfig delete hook.
426 | *
427 | * Called every time, a site get's removed.
428 | *
429 | * @uses update()
430 | *
431 | * @param string $event_name the event/action name
432 | * @param array $data the vhost data
433 | */
434 | function delete($event_name, $data) {
435 | global $app, $conf;
436 |
437 | $this->action = 'delete';
438 |
439 | $app->uses('getconf');
440 | $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
441 |
442 | if ($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') {
443 | $this->vhost_helper('delete', $data);
444 | }
445 |
446 | if ($data['old']['type'] == 'alias') {
447 | $data['new']['type'] == 'alias';
448 | $this->update($event_name, $data);
449 | }
450 |
451 | if ($data['old']['type'] == 'subdomain') {
452 | $data['new']['type'] == 'subdomain';
453 | $this->update($event_name, $data);
454 | }
455 | }
456 |
457 | /**
458 | * ISPConfig client delete hook.
459 | *
460 | * Called every time, a client gets deleted.
461 | *
462 | * @uses vhost_helper()
463 | *
464 | * @param string $event_name the event/action name
465 | * @param array $data the vhost data
466 | */
467 | function client_delete($event_name, $data) {
468 | global $app, $conf;
469 |
470 | $app->uses('getconf');
471 | $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
472 |
473 | $client_id = intval($data['old']['client_id']);
474 | $client_vhosts = array();
475 | $client_vhosts = $app->dbmaster->queryAllRecords('SELECT domain FROM web_domain WHERE sys_userid = '. $client_id .' AND parent_domain_id = 0');
476 |
477 | if (count($client_vhosts) > 0) {
478 | foreach($client_vhosts as $vhost) {
479 | $data['old']['domain'] = $vhost['domain'];
480 | $this->vhost_helper('delete', $data);
481 |
482 | $app->log('Removing vhost file: '. $data['old']['domain'], LOGLEVEL_DEBUG);
483 | }
484 | }
485 | }
486 |
487 |
488 | /**
489 | * ISPConfig internal debug function.
490 | *
491 | * Function for easier debugging.
492 | *
493 | * @param string $command executable command to debug
494 | */
495 | private function _exec($command) {
496 | global $app;
497 |
498 | $app->log('exec: '. $command, LOGLEVEL_DEBUG);
499 | exec($command);
500 | }
501 |
502 |
503 | /**
504 | * Helps managing vhost config files.
505 | *
506 | * This functions helps to create/delete and link/unlink vhost configs on disk.
507 | *
508 | * @param string $action the event/action name
509 | * @param array $data the vhost data
510 | * @param mixed $tpl vhost template to proceed
511 | *
512 | * @return $data['vhost'] the vhost data
513 | */
514 | private function vhost_helper($action, $data, $tpl = '') {
515 | global $app;
516 |
517 | $app->uses('system');
518 |
519 | //* $VAR: location of nginx vhost dirs
520 | $nginx_vhosts = '/etc/nginx/sites-available';
521 | $nginx_vhosts_enabled = '/etc/nginx/sites-enabled';
522 |
523 | $data['vhost'] = array();
524 |
525 | $data['vhost']['file_old'] = escapeshellcmd($nginx_vhosts .'/'. $data['old']['domain'] .'.vhost');
526 | $data['vhost']['link_old'] = escapeshellcmd($nginx_vhosts_enabled .'/'. $data['old']['domain'] .'.vhost');
527 | $data['vhost']['file_new'] = escapeshellcmd($nginx_vhosts .'/'. $data['new']['domain'] .'.vhost');
528 | $data['vhost']['link_new'] = escapeshellcmd($nginx_vhosts_enabled .'/'. $data['new']['domain'] .'.vhost');
529 |
530 | if (is_file($data['vhost']['file_old'])) {
531 | $data['vhost']['file_old_check'] = 1;
532 | }
533 |
534 | if (is_file($data['vhost']['file_new'])) {
535 | $data['vhost']['file_new_check'] = 1;
536 | }
537 |
538 | if (is_link($data['vhost']['link_old'])) {
539 | $data['vhost']['link_old_check'] = 1;
540 | }
541 |
542 | if (is_link($data['vhost']['link_new'])) {
543 | $data['vhost']['link_new_check'] = 1;
544 | }
545 |
546 | return $data['vhost'] = call_user_func(
547 | array(
548 | $this,
549 | "vhost_".$action
550 | ),
551 | $data,
552 | $app,
553 | $tpl
554 | );
555 | }
556 |
557 | /**
558 | * Creates the vhost file and link.
559 | *
560 | * @param array $data the vhost data
561 | * @param object $app ISPConfig app object
562 | * @param mixed $tpl vhost template to proceed
563 | *
564 | * @return $data['vhost'] the vhost data
565 | */
566 | private function vhost_insert($data, $app, $tpl) {
567 | global $app;
568 |
569 | $app->uses('system');
570 |
571 | $app->system->file_put_contents($data['vhost']['file_new'], $tpl);
572 |
573 | $data['vhost']['file_new_check'] = 1;
574 | $app->log('Creating vhost file: '. $data['vhost']['file_new'], LOGLEVEL_DEBUG);
575 | unset($tpl);
576 |
577 | if ($data['vhost']['link_new_check'] != 1) {
578 | exec('ln -s '. $data['vhost']['file_new'] .' '. $data['vhost']['link_new']);
579 | $data['vhost']['link_new_check'] = 1;
580 | $app->log('Creating vhost symlink: '. $data['vhost']['link_new_check'], LOGLEVEL_DEBUG);
581 | }
582 |
583 | return $data['vhost'];
584 | }
585 |
586 | /**
587 | * Updates the vhost file and link.
588 | *
589 | * @uses vhost_delete()
590 | * @uses vhost_insert()
591 | *
592 | * @param array $data the vhost data
593 | * @param object $app ISPConfig app object
594 | * @param mixed $tpl vhost template to proceed
595 | *
596 | * @return the vhost data
597 | */
598 | private function vhost_update($data, $app, $tpl) {
599 | global $app;
600 |
601 | $app->uses('system');
602 |
603 | $data['vhost']['link_new_check'] = 0;
604 |
605 | if ($data['new']['active'] == 'n') {
606 | $data['vhost']['link_new_check'] = 1;
607 | }
608 |
609 | $data['vhost']['file_new_check'] = 0;
610 |
611 | $this->vhost_delete($data, $app);
612 | return $this->vhost_insert($data, $app, $tpl);
613 | }
614 |
615 | /**
616 | * Deletes the vhost file and link.
617 | *
618 | * @param array $data the vhost data
619 | * @param object $app ISPConfig app object
620 | * @param mixed $tpl vhost template to proceed
621 | */
622 | private function vhost_delete($data, $app, $tpl = '') {
623 | global $app;
624 |
625 | $app->uses('system');
626 |
627 | if ($data['vhost']['file_old_check'] == 1) {
628 | $app->system->unlink($data['vhost']['file_old']);
629 | $data['vhost']['file_old_check'] = 0;
630 | $app->log('Removing vhost file: '. $data['vhost']['file_old'], LOGLEVEL_DEBUG);
631 | }
632 |
633 | if ($data['vhost']['link_old_check'] == 1) {
634 | $app->system->unlink($data['vhost']['link_old']);
635 | $data['vhost']['link_old_check'] = 0;
636 | $app->log('Removing vhost symlink: '. $data['vhost']['link_old'], LOGLEVEL_DEBUG);
637 | }
638 | }
639 |
640 |
641 | /**
642 | * Helps managing SSL cert files.
643 | *
644 | * This functions helps to create/delete and link/unlink SSL cert files on disk.
645 | *
646 | * @param string $action the event/action name
647 | * @param array $data the vhost data
648 | *
649 | * @return $data['cert'] the cert data
650 | */
651 | private function cert_helper($action, $data) {
652 | global $app;
653 |
654 | $app->uses('system');
655 |
656 | $data['cert'] = array();
657 | $suffix = 'nginx';
658 | $ssl_dir = $data['new']['document_root'] .'/ssl';
659 |
660 | $data['cert']['crt'] = escapeshellcmd($ssl_dir .'/'. $data['new']['ssl_domain'] .'.crt');
661 | $data['cert']['bundle'] = escapeshellcmd($ssl_dir .'/'. $data['new']['ssl_domain'] .'.bundle');
662 | $data['cert'][$suffix .'_crt'] = escapeshellcmd($ssl_dir .'/'. $data['new']['ssl_domain'] .'.'. $suffix .'.crt');
663 |
664 | if (is_file($data['cert']['crt'])) {
665 | $data['cert']['crt_check'] = 1;
666 | }
667 |
668 | if (is_file($data['cert'][$suffix .'_crt'])) {
669 | $data['cert'][$suffix .'_crt_check'] = 1;
670 | }
671 |
672 | if (is_file($data['cert']['bundle'])) {
673 | $data['cert']['bundle_check'] = 1;
674 | }
675 |
676 | return $data['cert'] = call_user_func(
677 | array(
678 | $this,
679 | "cert_".$action
680 | ),
681 | $data,
682 | $app,
683 | $suffix
684 | );
685 | }
686 |
687 | /**
688 | * Creates the ssl cert files.
689 | *
690 | * @param array $data the vhost data
691 | * @param object $app ISPConfig app object
692 | * @param string $suffix cert filename suffix
693 | */
694 | private function cert_insert($data, $app, $suffix) {
695 | global $app;
696 |
697 | $app->uses('system');
698 |
699 | if ($data['cert']['crt_check'] == 1) {
700 | if ($data['cert']['bundle_check'] == 1) {
701 | exec('(cat '. $data['cert']['crt'] .'; echo ""; cat '. $data['cert']['bundle'] .') > '. $data['cert'][$suffix .'_crt']);
702 | $app->log('Merging ssl cert and bundle file: '. $data['cert'][$suffix .'_crt'], LOGLEVEL_DEBUG);
703 | } else {
704 | $app->system->copy($data['cert']['crt'], $data['cert'][$suffix .'_crt']);
705 | $app->log('Copying ssl cert file: '. $data['cert'][$suffix .'_crt'], LOGLEVEL_DEBUG);
706 | }
707 | } else {
708 | $app->log('Creating '. $suffix .' ssl files failed', LOGLEVEL_DEBUG);
709 | }
710 | }
711 |
712 | /**
713 | * Changes the ssl cert files.
714 | *
715 | * @uses cert_delete()
716 | * @uses cert_insert()
717 | *
718 | * @param array $data the vhost data
719 | * @param object $app ISPConfig app object
720 | * @param string $suffix cert filename suffix
721 | */
722 | private function cert_update($data, $app, $suffix) {
723 | global $app;
724 |
725 | $this->cert_delete($data, $app, $suffix);
726 | $this->cert_insert($data, $app, $suffix);
727 | }
728 |
729 | /**
730 | * Removes the ssl cert files.
731 | *
732 | * @param array $data the vhost data
733 | * @param object $app ISPConfig app object
734 | * @param string $suffix cert filename suffix
735 | */
736 | private function cert_delete($data, $app, $suffix) {
737 | global $app;
738 |
739 | $app->uses('system');
740 |
741 | if ($data['cert'][$suffix .'_crt_check'] == 1) {
742 | $app->system->unlink($data['cert']['nginx_crt']);
743 | $app->log('Removing ssl cert file: '. $data['cert'][$suffix .'_crt'], LOGLEVEL_DEBUG);
744 | }
745 | }
746 |
747 | }
748 |
--------------------------------------------------------------------------------