Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing different HOST headers to be used in ng serve #6349

Closed
Tommyf opened this issue May 17, 2017 · 31 comments
Closed

Allowing different HOST headers to be used in ng serve #6349

Tommyf opened this issue May 17, 2017 · 31 comments
Labels
freq1: low Only reported by a handful of users who observe it rarely type: bug/fix

Comments

@Tommyf
Copy link

Tommyf commented May 17, 2017

Bug Report or Feature Request (mark with an x)

- [   ] bug report -> please search issues before submitting
- [ x ] feature request

Allow ng serve to accept requests with host headers that are different to the --host setting. This is needed when accessing the server via a reverse proxy.

Versions.

@angular/cli: 1.0.3
node: 6.10.1
os: linux x64
@angular/common: 4.1.2
@angular/compiler: 4.1.2
@angular/core: 4.1.2
@angular/forms: 4.1.2
@angular/http: 4.1.2
@angular/platform-browser: 4.1.2
@angular/platform-browser-dynamic: 4.1.2
@angular/router: 4.1.2
@angular/cli: 1.0.3
@angular/compiler-cli: 4.1.2

Linux Ubuntu 16.04.2 LTS

Repro steps.

ng new my-dream-app
cd my-dream-app/
ng serve

Configure reverse proxy (Apache/Nginx/HAProxy etc)
e.g. http://myapp.example.com reverse proxies to http://localhost:4200

Browse to http://myapp.example.com

Resulting page displays:
Invalid Host Header

The log given by the failure.

No error log is produced

Desired functionality.

I would like to see a command-line option that specifies a list of allowed HOST: header values.

Mention any other details that might be useful.

It is possible to work around this problem by editing the hosts file on your OS so that myapp.example.com points to an IP address that the server is listening on. This way, the 'expected' HOST: header is correct and ng serve is listening on the correct IP address.
However this is not an ideal solution as it requires editing the system-wide hosts file. This may not always be possible or desirable. It is common to allow for different HOST: headers to be used in server applications (e.g. Apache, Nginx etc) for virtual hosting.
I understand that ng serve is not meant for production purposes, so virtual hosting does not need to be a consideration, but sometimes developers also need to use a reverse proxy when working remotely rather than on their local machine (e.g. local machine is Windows and you don't want to run node locally).

After researching this issue more, I found that --host 0.0.0.0 was a common solution to this problem but no longer works due to a regression introduced in 1.0.1. due to stricter host name checking in WebPack. I see other issues related to it ( #6070 ), but they talk about disabling host checking (bad) or configuring public hosts (Using --public in webpack-dev-server or --piblic-host in angular-cli v1.1.0.beta.1 or newer.)

I tried installing Angular-cli 1.1.0-rc.0 and using --public-host http://public.host.com and --host 0.0.0.0 or --host <local IP Addr> but it still returns the Invalid Host header error when I browse to http://public.host.com

In one of the many threads I have read on this in the last few days, someone mentioned that Django has a configuration to allow multiple hosts and indeed it does. But it's done as a part of the configuration of the app by definign an array of allowed hosts. Can something like this be done?

@Tommyf
Copy link
Author

Tommyf commented May 17, 2017

So I was looking around more. There is a veritable spiders web of issues pertaining to problems since the host checking was implemented in webpack-dev-server.

And I just noticed this webpack/webpack-dev-server#899 which allows for passing in a list of allowed hosts in webpack-dev-server.

Can angular-cli somehow implement a similar list of allowed hosts and pass this on to webpack?

@lighter
Copy link

lighter commented May 17, 2017

I have same problem.

@ryanper
Copy link

ryanper commented May 17, 2017

I have a similar issue, I am also using service workers so using ng serve with ssl so will need to check how this will work. I am no expert but happy to look at this with some guidance.

@Tommyf
Copy link
Author

Tommyf commented May 17, 2017

I too am happy to work on this (with guidance).

@ryanper
Copy link

ryanper commented May 17, 2017

Looks like some work has already been done on this in v1.1.0-beta.1, will install and try this out.

Yep, this seems to work for me though using it with ssl may be an issue, or related to something else.

@Tommyf
Copy link
Author

Tommyf commented May 17, 2017

I mentioned using v1.1.0-rc.0 which includes that commit.

What I am asking for is different. In that commit, one needs to --disable-host-check which is bad as it just circumvents the security measures that were put in place in webpack-dev-server.
Also in that commit is the --public-host option. Although this is tecnically an 'allowed host' it's not as flexible as having a configuration setting with an array of allowed hosts. There are multiple use cases where only allowing a single 'public' host may not be sufficient, for example, branding based on URL, or needing to used different reverse proxies for different locations.

As an aside, the --public-host was not working for me in v1.1.0.rc.0. I still need to use my hosts file or use --disable-host-check. I will double check though.

@sumitarora sumitarora self-assigned this May 17, 2017
@sumitarora sumitarora added freq1: low Only reported by a handful of users who observe it rarely type: bug/fix labels May 17, 2017
@clydin
Copy link
Member

clydin commented May 18, 2017

The --public-host option expects a hostname. The use of a URL was most likely the cause of the issue observed.
Until webpack-dev-server adds support for configuring multiple hosts, there's not much that can done on that front, unfortunately.
Realistically, ng serve is meant to be a basic development server. If a development setup requires a more exotic configuration, a custom server used in combination with ng build --watch may be more appropriate.
Also, there's nothing inherently bad about --disable-host-check. It's a tool that can be quite useful if used appropriately. Regardless of the use of the option, ng serve is not intended to be publicly accessible.

@Tommyf
Copy link
Author

Tommyf commented May 18, 2017

If I use a hostname instead of a URL for --public-host, I get the following error:

'live-reload-client' must be a full URL.

I agree that this cannot be done until the multiple hosts is added to a webpack-dev-server release. It looks like it's being added in webpack/webpack-dev-server#899 , but i'm not sure if/when that will be released.

Can this be revisited once the above is indeed released in webpack-dev-server?

@ryanper
Copy link

ryanper commented May 18, 2017

Opps sorry @Tommyf you did mention v1.1.0-rc.0 my bad.

With regard to the full url, these combination of parameters worked for me
a) "ng serve --host host-ip-address --public-host http://host-ip-address" ( had to add http:// )
b) "ng serve --host 0.0.0.0 --disable-host-check",

I am happy with the --disable-host-check flag for local development, but I can appreciate the need to secure it in larger development teams where a proper web server would most likely be used as clydin suggested.

@Tommyf
Copy link
Author

Tommyf commented May 18, 2017

@ryanper in that example, you have the same IP address used for --host and --public-host? If that's the case, then this is not the scenario I am talking about.

The scenario I am talking about is this:

ng serve --host local-ip-address --public-host http://public-ip-address-or-dns

Where local-ip-address is on a private network and not accessibly directly from the web and you have a reverse proxy that maps the public ip to the local one. In the above instance, you only get Invalid Host header unless you add --disable-host-check also.

In this scenario, running the following

ng serve --host 0.0.0.0 --disable-host-check

will load the page, but the websocket for live updates will not connect as it tries to use http://localhost:4200 which is obviously not accessible from the net :)

@mikkoh85
Copy link

mikkoh85 commented May 18, 2017

Can you tell me what is this about?

When I run
ng serve --host 0.0.0.0 --disable-host-check

The option '--disable-host-check' is not registered with the serve command. Run `ng serve --help` for a list of supported options. appears. And it gives that same Invalid Host header. I tried to update package.json from 4.1.1 everything to 4.1.2 and hit npm i and the same "is not registered" comes just like before.

I have these installed globally:

/usr/lib
├── @angular/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

@clydin
Copy link
Member

clydin commented May 18, 2017

@Tommyf the scenario you're describing is really not recommended. 'ng serve' is not a production ready or security hardened server; and is not intended to be.
The settings being discussed are intended to enable the creation of internal production representative development environments. Docker is quite popular for this.

@mikkoh85 the option will be available in version 1.1 of the CLI. A release candidate is available currently.

@mikkoh85
Copy link

@clydin thank you for this info, I guess I read it in a bit of hurry :)

@Tommyf
Copy link
Author

Tommyf commented May 19, 2017

@clydin I understand that this is not production for production use. The scenarios I talk of are all for development only. I can list out feasible development scenarios for this if needed.

I came across this problem as I was going through the basic tutorial for using angular-cli. I imagine I am not the only one running into this problem. Although I found workarounds (Hosts file, and now the --disable-host-checks option in the as-of-yet unreleased versions), I feel it would be good if this stuff would work more easily for people new to angular-cli who want to have a remote, non-publicly-routable development server without having to jump through hoops.

Also, could you please clarify the purpose of the --public-host option? I was under the impression that it was intended for this purpose, where the public host is different to the listening host, but if this is not a recommended scenario, what is the real purpose of that option?

@clydin
Copy link
Member

clydin commented May 19, 2017

I suppose "public" is somewhat of a misnomer. However, it is more succinct than "host that will actually be used to access the application". Also, as the need for these options (and their very existence) is fairly recent, documentation has not fully caught up yet.

A fairly common setup that would need to leverage the option is to encapsulate the CLI within a Docker container. Sharing a preconfigured container within a development team has the potential vastly simplify team development workflows as well as on-boarding of new members.
More extensive setups leverage multi-container configurations allowing for API, DB, or reverse proxy servers. These setups allow for a fairly comprehensive mimicking of a final production deployment and all within one local machine.

A typical workflow for ng serve is one of local development. Running ng serve in combination with an IDE and a web browser; allowing for code changes to be quickly visualized, experimented upon, and adjusted in near realtime.

@Tommyf
Copy link
Author

Tommyf commented May 19, 2017

Shouldn't the "host that will actually be used to access the application" work without needing to use --ignore-host-check though? Surely it should be a valid host name, otherwise the option does not make sense?

I do understand what you are saying, I myself am just trying to do 'local' development, but for various reasons, I cannot have my dev environment on my local machine.

  1. I am on Windows and don't wish to run node on Windows.
  2. I switch between computers - desktop at home, laptop on the commute.

For these reasons, my dev server is not on my local machine, but I still want to use it in the same manner as if it were (with exception of it auto-launching a browser). The available options, especially the new ones, suggest that this should be possible without having to circumvent the security restrictions (Which, I agree, aren't real security holes in this kind of scenario, but forcing people to circumvent them can cause bad practices to form).

Is it OK to discuss like this in here? I'm wary of being too chatty in what is essentially an issue reporting forum.

@clydin
Copy link
Member

clydin commented May 23, 2017

@Tommyf You can read more in-depth about the underlying security issue here: webpack/webpack-dev-server#887

Also you might want to look into using a Docker setup to encapsulate the dev dependencies (node, the cli, etc.). There was a talk at this year's ng-conf (https://www.youtube.com/watch?v=socWfhPJptE).

@JSMike
Copy link
Contributor

JSMike commented May 24, 2017

I'm also having this issue after updating from 1.0.0 to 1.0.4, with Angular-CLI in a docker container, hosting to 0.0.0.0, when trying to access the served page via the docker-machine ip address.

@johanchouquet
Copy link

johanchouquet commented Jun 21, 2017

I use Docker in my workflow in order to develop in the same conditions from dev to prod. I'm on Win 7 so I use Docker toolbox. Everything was working fine with angular-cli v1.0.0. The problem with the next updates of cli (from webpack-dev-server) is that now the command ng serve -H 0.0.0.0 --environment=docker does not work anymore.

I saw a lot of issues on the web, and that blocks me from updating my components (angular-cli) to get newest features.

For now, it doesn't matter since there is no crucial feature that I'm awaiting, but I fear that soon, it will the case. I've seen and tested several workarounds. But every workaround I tried also has impacts on live-reload. So, for now, all I can do is force the angular-cli version 1.0.0, which is working fine.

Hopefully https://github.com/webpack/webpack.js.org/blob/master/content/configuration/dev-server.md#devserverallowedhosts will be available in webpack and angular-cli. Hopefully, my use case will be taken into account. I need to connect with a Docker container to localhost (from the container) which is by default the IP address of the container: http://192.168.99.100.

Any plans / news on it ?

@glebmachine
Copy link

Please add this flag to webpack:
image

@JSMike
Copy link
Contributor

JSMike commented Jul 28, 2017

this already exists: #6173

This issue should be closed.

@haydenk
Copy link

haydenk commented Aug 1, 2017

I can see how this would be useful in development...

Configure reverse proxy (Apache/Nginx/HAProxy etc)

but I hope you're not running ng serve in production.

@glebmachine
Copy link

glebmachine commented Aug 1, 2017 via email

@briansanchez
Copy link

this works like a charm:
ng serve --host 207.68.230.134 --disable-host-check

ankon added a commit to ankon/skf-flask that referenced this issue Sep 8, 2017
`ng serve` is running behind a reverse proxy in the docker images, so that check is somewhat pointless. For actual
production environments `ng serve` must not be used at all.

See also angular/angular-cli#6349
@andela-andrewmakenzi
Copy link

andela-andrewmakenzi commented Nov 2, 2017

There are two ways of doing this :

  1. Do and ng eject and add disableHostCheck=true to devServer settings in the webpack.config.js file then run ng s to serve that app, hostChecking will be disabled OR
  2. Run this on your command line ng serve --host 0.0.0.0 -port 4200 --disable-host-check
    It is important to note that if you disable host checking, your server is susceptible to DNS rebinding attacks, which might not matter depending on what you are trying to do.

@haydenk
Copy link

haydenk commented Jan 7, 2018

Why is this doing a host check at all? Wouldn't, nay shouldn't, this only be used during local development of the web application?

@glebmachine
Copy link

glebmachine commented Jan 7, 2018 via email

@dineshmaths1
Copy link

Am using Angular CLI: 6.2.2 , Node: 8.11.1 and OS: darwin x64 This is my etc hosts 127.0.0.1 dinesh.mysocialapi.com

This is my comment node_modules/@angular/cli/bin/ng serve --host 0.0.0.0 --disableHostCheck true

am getting this error how to fix ? Loading failed for the with source “http://dinesh.mysocialapi.com/vendor.js”. dinesh.mysocialapi.com:34

@leventguney
Copy link

I have edited the serve block under architect block in angular.json file to define publicHost property and it works. I can use ng serve directly and it works with my host name without complaining invalid host header

"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "my-app:build",
"publicHost":"myapp.com"
},
"configurations": {
"production": {
"browserTarget": "my-app:build:production"
}
}
},

@clydin
Copy link
Member

clydin commented Sep 6, 2019

Please note that a DNS Rebinding attack allows a malicious website to access resources within the local network including localhost. So it is not a matter of trusting localhost but rather trusting every website visited from the computer.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Oct 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
freq1: low Only reported by a handful of users who observe it rarely type: bug/fix
Projects
None yet
Development

No branches or pull requests