How to use browsersync with an apache vhost on same port? - macos

I know there are a lot of similar questions on SO and GitHub about this but none are working in my case.
I need for a project to use gulp + browsersync with an apache vhost (created with MAMP PRO 5.5).
Gulp is working (it does all the tasks I need). Browsersync is set up but it opens my website on a different port that the one which is used by MAMP. I've tested with default Port and Mamp default port. Browsersync still opens the website with the correct url but not the correct port.
I understand that I can't use the same port but how can I set up Browsersync ?
Here is my gulp relevant part :
gulp.task('browser-sync', ['sass', 'scripts'], function () {
browserSync.init({
open: 'external',
host: 'my-domain.dev',
proxy: 'my-domain.dev',
https: {
key: "/Users/path-to-custom-certificate/my-domain.dev.key",
cert: "/Users/path-to-custom-certificate/my-domain.dev.crt"
},
//port: 443, // If I try same port as MAMP, Browsersync increments this port ex 444
browser: "google chrome"
});
});
Mybe something can be configured in APACHE ?

I hesitated to delete my question but in case it could helps :
Finally, it appears that my Browsersync code is correct. When I run gulp, it opens the wrong url with the Browsersync default port :
https://my-domain.dev:3000
But when I open the correct url (my-domain.dev) set in apache, Browsersync is connected and reloads that page.

Related

Lets-encrypt Error: Failed HTTP-01 Pre-Flight / Dry Run

I've set up a redbird based proxy following its README file examples.
By now I've configured single domain both for http and https and it's working well (https still using self-signed certificate).
But now I'm trying to configure it to use letsencrypt to automatically get valid ssl certificates and I'm getting stuck in following error:
{"level":30,"time":1578681102208,"pid":21320,"hostname":"nigul","name":"redbird","0":false,"1":"setChallenge called for 'exposito.bitifet.net'","msg":"Lets encrypt debugger","v":1}
[acme-v2] handled(?) rejection as errback:
Error: Error: Failed HTTP-01 Pre-Flight / Dry Run.
curl 'http://exposito.bitifet.net/.well-known/acme-challenge/test-cf55199519d859042f695e620cca8dbb-0'
Expected: 'test-cf55199519d859042f695e620cca8dbb-0.MgLl7GIS59DPtPMejuUcXfddzNt8YxfLVo5op670u8M'
Got: '<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
'
See https://git.coolaj86.com/coolaj86/acme-v2.js/issues/4
at /home/joanmi/SERVICES/redbird_domains/node_modules/acme-v2/index.js:49:10
at process._tickCallback (internal/process/next_tick.js:68:7)
As far as I understand, this is telling me that Lets Encrypt is trying to access to the url http://exposito.bitifet.net/.well-known/acme-challenge/test-cf55199519d859042f695e620cca8dbb-0 using the following command:
curl 'http://exposito.bitifet.net/.well-known/acme-challenge/test-cf55199519d859042f695e620cca8dbb-0'
...and that it is getting which seems a 404 HTML Error page which I have no clue wherever it could come.
And, in fact, executing that curl command or just pasting that url in my browser (you can try it: I left the server running), I get the given Expected string so, from my point of view it seems like if my configuration were correct but, for some reason, Lets Encrypt's servers were reaching another server (either because of wrong routing or DNS).
But on the other hand, I suppose it's more probable that I've done something wrong in my configuration.
Here I paste my whole script (ports 80 and 443 are redirected to 1080 and 1443, respectively, through iptables because the script is run by non privileged user):
const Redbird = require("redbird");
const proxy = Redbird({
port: 1080,
xfwd: false, // Disable the X-Forwarded-For header
letsencrypt: {
path: __dirname + '/certs',
port: 9999
// LetsEncrypt minimal web server port for handling challenges.
// Routed 80->9999, no need to open 9999 in firewall. Default 3000
// if not defined.
},
ssl: {
http2: true,
port: 1443, // SSL port used to serve registered https routes with LetsEncrypt certificate.
}
});
proxy.register('exposito.bitifet.net:9999', 'http://localhost:8001', {
ssl: {
letsencrypt: {
email: 'xxxxxx#gmail.com', // Domain owner/admin email
production: false,
// WARNING: Only use this flag when the proxy is verified to
// work correctly to avoid being banned!
}
}
});
proxy.register("exposito.bitifet.net", "http://localhost:8001");
Any clue will be welcome.
Thanks.
SOLVED!!
Many issues were involved at the same time (despite my lack of experience with either redbird and letsencrypt.
The magic 404/Not found page: I guess it came from a lighttpd server that seems to had been preinstalled in my VPS.
Port 80 was redirected via iptables but I suppose in one or other configuration tweak I could have redirected incoming requests to localhost's port 80 (which is not redirected).
My redbird missunderstanding: Looking at examples in its README file, I thought redbird were kinda "multi- reverse_proxy" in the sense that you could redirect http and https requests with single redbird instance.
But I finally realized that the (maybe not so well named) port option which is, in fact, an http port, serves only to configure a built-in unconditional http->https redirector (of which I already had read about, but I thought it were optional).
The actual underlying issue: If your DNS have DNSSEC activated, you should define a CAA register in it pointing to letsencrypt.org.
At the moment I disabled DNSSEC instead because my provider's control panel doesn't allow me to create such register.
I discovered it while trying to get the certificates through certbot (sudo apt-get install certbot which I must say that, If I had known about it before, I wouldn't had care about trying redbird's letsencrypt integration.
It is much more verbose (while redbird is more like a black box when errors arise) and pointed out that I needed the CAA register.
Here the notes I took about it (in case anyone could be interested):
Free SSL Certificates with Certbot
Install certbot:
sudo apt-get install certbot
Create:
sudo certbot certonly --manual --preferred-challenges http -d <domain>
Renew:
sudo certbot renew
Caveats:
DNSSEC
If your DNS server has DNSSEC enabled, you will need to add a CAA
register pointing to letsencrypt.org.
...and your DNS provider my not allow to create it (at least I
couldn't with CDMON. Also not -yet- complained).
production = false is for other kinds of testing: I read that if you put in to true while testing, you may be banned from letsencrypt if you perform too many requests.
Setting it to false you can test redirections, but you will see still errors regarding letsencrypt even you could navigate without a secure certificate (I think kinda self-signed is provided to allow testing). So don't expect a valid one.
ssl port is used for redirection: Not a (big) issue, but if you specify ssl port other than 443, built in redirector will unconditionally redirect you to that port.
Running redbird as root and using standard (80 and 443) ports works fine. But if you, like me, want to use an alternative ports in order to execute redbird with non privileged user, you will get redirected to that alternative port instead of 443 (Even having it redirected through iptables).
Here my (almost*) final redbird script:
const Redbird = require("redbird");
const proxy = Redbird({
port: 1080,
xfwd: false, // Disable the X-Forwarded-For header
ssl: {
port: 1443,
},
letsencrypt: {
path: __dirname + '/certs',
port: 9999,
// LetsEncrypt minimal web server port for handling challenges.
// Routed 80->9999, no need to open 9999 in firewall. Default 3000
// if not defined.
},
});
proxy.register('exposito.bitifet.net', 'http://exposito.bitifet.net:8001', {
ssl: {
http2: true,
letsencrypt: {
email: 'xxxxxx#gmail.com', // Domain owner/admin email
production: true,
// WARNING: Only use this flag when the proxy is verified to
// work correctly to avoid being banned!
},
}
});
(*) I still need to fix the explicit-port redirection issue (5), because I don't want to run redbird as root. But I know is possible to allow uses to listen given ports. Even I would probably better try to patch redbird in order to allow specifying listen and redirection ports separatedly.
EDIT: It is already implemented (and documented) using the (optional) option redirectPort in ssl section. Just added redirectPort: 443 and job done!!
EDIT 2: For the sake of completion, there still was another issue I struggled with.
To get things working I finally configured the redirection to the http port instead of https one.
That is: Incomming https requests gets redirected to my application http port.
It seems weird but it works. At least if you don't need any exclusively https feature such as push notifications (which I plan to use in the future).
But its implies to open an http server at least on localhost. Which isn't a major issue now (this is only a playground server) but I plan to use redbird at work to proxy multiple domains to different servers so that would had forced us to open http at least in our DMZ vlan (which is an additional risk that is better to avoid...).
When I tried redirecting to https I got the DEPTH_ZERO_SELF_SIGNED_CERT error.
Ok: This is telling me that redbird (or node) does not trust my original (self signed) certificate. I know there is an option to tell node to accept those certificates. But maybe it is not the way to go...
So I configured my application to use the same certificate that redbird is obtaining through letsencrypt.
But then I got this other error:
UNABLE_TO_VERIFY_LEAF_SIGNATURE
Researching a bit I found this StackOverflow answer that explains how to get all root and intermediate certificates trusted by Mozilla and make node to trust them.
So, at the end, what I did was:
Installed node_extra_ca_certs_mozilla_bundle package:
npm install --save node_extra_ca_certs_mozilla_bundle
Prepended NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem to the start command in the package.json's scripts section.
Updated my redbird script to point again to the https (protocol and) port:
proxy.register('exposito.bitifet.net', 'https://localhost:4301', {...]);
Here my final redbird configuration:
const Redbird = require("redbird");
const proxy = Redbird({
port: 1080,
xfwd: false, // Disable the X-Forwarded-For header
ssl: {
port: 1443,
redirectPort: 443
// key: "/etc/bitifet/exposito/ssl/private.key",
// cert: "/etc/bitifet/exposito/ssl/public.cert",
},
letsencrypt: {
path: __dirname + '/certs',
port: 9999,
// LetsEncrypt minimal web server port for handling challenges.
// Routed 80->9999, no need to open 9999 in firewall. Default 3000
// if not defined.
},
});
proxy.register('exposito.bitifet.net', 'https://localhost:4301', {
ssl: {
http2: true,
letsencrypt: {
email: 'xxxxxx#gmail.com', // Domain owner/admin email
production: true,
// WARNING: Only use this flag when the proxy is verified to
// work correctly to avoid being banned!
},
}
});
And here my package.json file contents:
{
"name": "redbird_domains",
"version": "0.0.1",
"description": "Local Domains Handling",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node ./index.js"
},
"author": "Joanmi",
"license": "GPL-3.0",
"dependencies": {
"node_extra_ca_certs_mozilla_bundle": "^1.0.4",
"redbird": "^0.10.0"
}
}

How to make Laravel Valet work nicely with BrowserSync?

Has anyone made Laravel Valet (secure) work nicely with Browser Sync while using Laravel Mix. I am doing something like this but it keeps pointing me to https://shadow-api.test:3000 where as I simply want to omit the port.
mix.browserSync({
proxy: 'shadow-api.test',
host: 'shadow-api.test',
open: 'external',
https: {
key: "/Users/aligajani/.config/valet/Certificates/shadow-api.test.key",
cert: "/Users/aligajani/.config/valet/Certificates/shadow-api.test.crt"
}
});
For your information, I am using the latest versions of everything, fresh install and intend on building a SPA (with token auth). I haven't had similar issues with BrowserSync before simply because I wasn't using Valet.
Better late than never.. this works for me:
.browserSync({
proxy: 'https://mass-importer.faaren.test',
host: 'mass-importer.faaren.test',
open: 'external',
https: {
key: "/Users/fabianhagen/.config/valet/Certificates/mass-importer.faaren.test.key",
cert: "/Users/fabianhagen/.config/valet/Certificates/mass-importer.faaren.test.crt"
}
});
I had to prefix the proxy domain with https://. It still opens under port 3000 (or another if this port is already used), but browsersync is working.

Getting subdomains to work locally with Laravel

I am having a hard time getting subdomains to work locally. I have Docker serving the application to port 8080, and I am able to see the Laravel welcome screen. I then have a simple route setup like this:
Route::domain('{name}.localhost:8087')->group(function () {
return 'Hello World';acrylic dns
});
I am using Laravel's basic server, i.e. php artisan serve --host=0.0.0.0 --port=8087
When I try and view the page, nothing happens. It just goes to the welcome screen. I have even tried adding 'test.localhost' to the /etc/hosts file. Couple questions:
1) Can you have the port in the host like I have it there (in the Laravel route)?
2) I have seem somewhat similar posts where the solution was to use acrylic dns (on windows). I am using a Mac. Is this something where I need an actual DNS server?
3) I am planning on using nginx, do I need a 'beefier' web server to accomplish this?
With the basic Laravel server I have tried hard coding test.localhost in the route, with and without the port. I'm sure I am goofing something up, just not sure where. I am on a Mac, and I am running Laravel 5.6. Thanks in advance!
1) No, the web server configuration will listen on the port.
// nginx
server {
listen 8080;
...
}
2) You add the subdomains in your /etc/hosts file and create separate nginx configurations:
// /etc/hosts
subdomain1.foo.localhost 127.0.0.1
subdomain2.foo.localhost 127.0.0.1
subdomain3.foo.localhost 127.0.0.1
// nginx subdomain1.foo.localhost.conf
server {
listen 8080;
server_name subdomain1.foo.localhost;
...
}
// nginx subdomain2.foo.localhost.conf
server {
# set different port if needed
# listen 8082
listen 8080;
server_name subdomain2.foo.localhost;
...
}
// nginx subdomain3.foo.localhost.conf
server {
# set different port if needed
# listen 8083
listen 8080;
server_name subdomain3.foo.localhost;
...
}
3) Nginx is a production ready web server, you may need load balancers and multiple instances of the web servers to scale out, but nginx will be more than sufficient.
If you're using Artisan serve, go to
/etc/hosts (or similar)
127.0.0.1 subdomain.localhost
And open in the browser
subdomain.localhost:8087

valet local domain with browser sync Laravel mix

I have load laravel project which runs fine with valet domain something.dev
Tried to implement browser sync with laravel-mix
mix.browserSync({
proxy: 'something.dev'
});
After running npm run watch it is pointing me to http://localhost:3000/
Can i point to to valet domain instead of localhost:3000 ?
Here is the output of npm run watch
Asset Size Chunks Chunk Names
mix.js 2.59 kB 0 [emitted] mix
[Browsersync] Proxying: http://something.dev
[Browsersync] Access URLs:
--------------------------------------
Local: http://localhost:3000
External: http://192.168.1.131:3000
--------------------------------------
UI: http://localhost:3001
UI External: http://192.168.1.131:3001
--------------------------------------
[Browsersync] Watching files...
I had similar issues myself getting browserSync working with Valet, but the options I use are:
mix.browserSync({
proxy: 'something.test',
host: 'something.test',
open: 'external'
});
host overrides any detection of hostname in browserSync
open tells it which URL to open (local by default)
If you're using valet and ran into an issue where the browsersync doesn't start, here's the answer. I was banging my head on the wall over this but found a clue in their Upgrade to Mix 6 docs. After reading this, here's my setup:
// package.json
{
...
"scripts": {
"build": "mix --production",
"dev": "mix watch" // <--- add this script, you need to run mix watch
},
...
}
Then in my webpack.mix.js
// webpack.mix.js
const mix = require('laravel-mix');
const homedir = require('os').homedir();
const host = 'your-local-domain.test';
// ... other mix stuff
mix.browserSync({
hot: true,
ui: false,
proxy: `https://${host}`,
host,
port: 8080,
open: 'external',
notify: true,
files: ['**/*.php', 'dist/**/*.(js,css)'],
// if you're using valet with https, point to cert & key
https: {
key: `${homedir}/.config/valet/Certificates/${host}.key`,
cert: `${homedir}/.config/valet/Certificates/${host}.crt`,
},
});
Let me know if I'm missing anything!

Access an AngularJS app running on a Grunt-Proxy server inside a VM from the host

In our development environment we have Ubuntu VMs running on a Windows 7 host. We found that if we change the Gruntfile's "connect.options.hostname" to '0.0.0.0' we can hit our Angular app running in the VM from Internet Explorer in the host.
In order to avoid a cross-domain error when we hit some web services from Angular, we setup a Grunt-Proxy server. This works fine in the VM. From the host, any time the app tries to hit a web service it fails (since it's not on the proxy port) trying to access a server on port 9000 (the server is running on port 8888). From the host when I try to access the App on the proxy port (8050) I just get a 404 error - I'm not really sure how to proceed with this.
My proxy is setup as follows in the Gruntfile:
proxy: {
proxy1: {
options: {
port : 8050,
host : 'localhost',
router : {
'localhost/rest/*' : 'localhost:8888',
'localhost' : 'localhost:9000'
}
}
}
},
I tried playing with some of these settings but haven't had any luck. Any help would be appreciated.

Resources