rockymeza / wifi

[unmaintained] WiFi tools for linux
http://pypi.python.org/pypi/wifi
BSD 2-Clause "Simplified" License
305 stars 151 forks source link

Support for setting up access points using hostapd and dnsmasq #46

Open foosel opened 10 years ago

foosel commented 10 years ago

New wrappers for manipulating hostapd and dnsmasq configuration files and an AccessPoint class that combines hostapd, dnsmasq and scheme in order to set up an access point with dhcp, dns forwarding, local domain resolution and optionally also NATing to an existing interface.

Also adds support for static interfaces.

New dependency on the netaddr module had to be added in order to make the ip network handling for the access point mode less cumbersome.

Scheme now also support overwriting of existing configurations and more than one entry per configuration key in extended options (necessary for adding iptables/sysctl calls for post-up/pre-down events in /etc/network/interfaces).

rockymeza commented 10 years ago

Hi @foosel,

This is so awesome. Thank you so much for adding this pull request. I really want to read this code and get to understand what's going on, but I am going to be at DjangoCon this week so I will be super busy and probably won't have enough time to give this pull request the lookover it deserves. It looks like you are making a great addition to the codebase and I am so excited that there are people out there contributing to the project.

I won't be able to really give this pull request the time it needs this week, but I promise to give it the time it deserves when I can. In the meanwhile, I was wondering if you could put in some documentation about the new features and how/why you would want to use them. Also, it might be nice to have a little introduction to hostapd and dnsmasq (I have never used them before).

Thanks again!

foosel commented 10 years ago

Hi @rockymeza,

No worries about the time constraints, I know this kind of issue only too well myself.

Do you want me to add this kind of documentation to the docs folder or rather as some sort of addendum to this PR in comment form?

Since I didn't add flags to the wifi command to use that stuff I'd have to add a new library-only (at least for now) section to the documentation, if that's ok for you I can do that. Have to see myself though when I'll get around to do this, this PR is the result of me extending the lib in order to work on a little net connectivity daemon that in the future will be an addon to OctoPrint and is supposed to solve the hen-egg problem of having an embedded system without screen or input but only a web interface which you have to setup somehow to be able to connect to it, and I'm still fairly busy with getting that to work... :)

Cheers, Gina

rockymeza commented 10 years ago

Please see below

2014年9月2日 上午3:52于 "Gina Häußge" notifications@github.com写道:

Hi @rockymeza,

No worries about the time constraints, I know this kind of issue only too well myself. Thank you for being so understanding.

Do you want me to add this kind of documentation to the docs folder or rather as some sort of addendum to this PR in comment form? In the docs folder would be awesome.

Since I didn't add flags to the wifi command to use that stuff I'd have to add a new library-only (at least for now) section to the documentation, if that's ok for you I can do that. Yeah, that sounds great! Have to see myself though when I'll get around to do this, this PR is the result of me extending the lib in order to work on a little net connectivity daemon that in the future will be an addon to OctoPrint and is supposed to solve the hen-egg problem of having an embedded system without screen or input but only a web interface which you have to setup somehow to be able to connect to it, and I'm still fairly busy with getting that to work... :) That sounds fun!

Cheers, Gina Thanks again! -rocky

— Reply to this email directly or view it on GitHub.

rockymeza commented 10 years ago

Hi @foosel,

I've been reading up on dnsmasq and hostapd and I finally have a grasp on what's happening here. I think that this is a real cool application of the wifi library, but I don't know if this code needs to live in the wifi library itself. I think the purpose of wifi is just to connect to wireless networks, not to set them up.

In my opinion, the AccessPoint class might work better as it's own package, that way people who want the ability to make their computer the router have that power, but also those who don't need that functionality don't need to install it. On the wifi docs I could link to the access point library as well. What do you think about that? I'm still quite open to convinced that it should live in the wifi library.

I noticed that there are some changes in scheme.py. I think we should get these merged, but we need to do it in a backwards-compatible way. It looks like you are expecting a new attribute "type" (good) and for options to be a dictionary of lists. Let's figure out how to get these changes in.

rockymeza commented 10 years ago

@gavinwahl, what do you think?

foosel commented 10 years ago

@rockymeza sorry for just getting back to you now, very busy with other stuff. I can understand your reasoning and will look into separating the changes to the scheme class from the hostap stuff and factor that out into its own project. Might take a bit though, these days are way too short for all the work piling up ;)

The new type attribute should already be backwards compatible if I'm not mistaken, as should the other options type (which I added since there are things you might need to have to add to a scheme entry which can show up multiple times such as ip-up clauses). Please tell me if I've overlooked something here, but I'm fairly sure it shouldn't clash.

One other thing (not really related to this specific PR but since I'm talking to you anyways ;) ... would you be open to another PR changing again how the bash completion is installed? The problem is the following: If you install something that has the wifi library as it is now in its dependencies and install that via the usual setuptools route, the dependency will be pulled in and installed in a sandbox. If that installation now runs with superuser rights, the setup of wifi will attempt to add the bash completion config, but violate the sandbox by that, which aborts the installation. I made a modification to my version of the wifi lib which introduces a new install_extras command which takes care of putting the bash completion stuff at the right place, chmods them and all that (see my version, I also use that route now in netconnectd). It's either that or the original idea from the former PR for that issue to wrap a try-except-block around the installation I fear, otherwise wifi is unusuable as a plain library :/

rockymeza commented 10 years ago

That sounds good. Thanks for looking into that.

-rocky 2014年9月18日 上午3:58于 "Gina Häußge" notifications@github.com写道:

@rockymeza https://github.com/rockymeza sorry for just getting back to you now, very busy with other stuff. I can understand your reasoning and will look into separating the changes to the scheme class from the hostap stuff and factor that out into its own project. Might take a bit though, these days are way too short for all the work piling up ;)

The new type attribute should already be backwards compatible if I'm not mistaken, as should the other options type (which I added since there are things you might need to have to add to a scheme entry which can show up multiple times such as ip-up clauses). Please tell me if I've overlooked something here, but I'm fairly sure it shouldn't clash.

One other thing (not really related to this specific PR but since I'm talking to you anyways ;) ... would you be open to another PR changing again how the bash completion is installed? The problem is the following: If you install something that has the wifi library as it is now in its dependencies and install that via the usual setuptools route, the dependency will be pulled in and installed in a sandbox. If that installation now runs with superuser rights, the setup of wifi will attempt to add the bash completion config, but violate the sandbox by that, which aborts the installation. I made a modification to my version of the wifi lib which introduces a new install_extras command which takes care of putting the bash completion stuff at the right place, chmods them and all that (see my version https://github.com/foosel/wifi/blob/master/setup.py#L54, I also use that route now in netconnectd https://github.com/foosel/netconnectd). It's either that or the original idea from the former PR for that issue to wrap a try-except-block around the installation I fear, otherwise wifi is unusuable as a plain library :/

— Reply to this email directly or view it on GitHub https://github.com/rockymeza/wifi/pull/46#issuecomment-55950664.

GusBricker commented 10 years ago

:( Oh i was very much looking forward to this getting merged into the wifi library.

rockymeza commented 10 years ago

Really? Like I said, I could be convinced to have it in the WiFi package. If you think this stuff would flourish better here, then maybe we should include it.

-rocky 2014年9月18日 下午1:54于 "GusBricker" notifications@github.com写道:

:( Oh i was very much looking forward to this getting merged into the wifi library.

— Reply to this email directly or view it on GitHub https://github.com/rockymeza/wifi/pull/46#issuecomment-55997890.

GusBricker commented 10 years ago

Well I just think the name of this package is wifi, which is pretty generic. So it would be nice if it could both manage connecting to networks and creating networks. If it was wifi-client or something like that, then I would understand the reason not to go down that path.

rockymeza commented 10 years ago

@GusBricker, That's pretty fair.

@foosel, I can't merge this without documentation, but I can help you to write the documentation. Do you have any examples of how you are using this? If you still want to get this into wifi, I think it's fair. I do feel a little guilty owning the wifi package name on PyPI and being such a small package. If you don't want to post the example usage on here, you can send it to my email, which is my github username at gmail.

foosel commented 10 years ago

@rockymeza I have not forgotten about this, I'm just drowning in (completely unrelated) code right now. Sorry for the lack of response, I will come around to this and we'll work something out, code and documentation wise, I promise.

rockymeza commented 10 years ago

No problem, I'm drowning in other stuff too, so please take your time

-rocky 2014年9月30日 上午3:25于 "Gina Häußge" notifications@github.com写道:

@rockymeza https://github.com/rockymeza I have not forgotten about this, I'm just drowning in (completely unrelated) code right now. Sorry for the lack of response, I will come around to this and we'll work something out, code and documentation wise, I promise.

— Reply to this email directly or view it on GitHub https://github.com/rockymeza/wifi/pull/46#issuecomment-57214515.

BadgerOps commented 10 years ago

I'm interested in @foosel 's changes too - seems like I'm working on a very similar project over at my repo. I'd be willing to do some testing / documentation if that would help.

foosel commented 10 years ago

Sorry for not having gotten back to this yet, still drowning in other stuff, but i have not forgotten it and it's still on my TODO list.

rockymeza commented 9 years ago

Hey, I plan on working on this after the New Year, but for the record I wanted to point out that somebody has put out a similar project called hotspotd. I hope that this doesn't make you lose hope. I want to try this out. I'm actually pretty interested in what we could do with this feature.

foosel commented 9 years ago

It's also still on my TODO list (and gets overtaken by higher prio stuff, big big sorry for that). Just FYI, it's working great in netconnectd.

BadgerOps commented 9 years ago

@foosel I'm still willing to assist where I can, let me know what I can do.

rockymeza commented 9 years ago

Hi @foosel,

I want to work on this.

Can you explain how I would go about using it?

foosel commented 9 years ago

Well, first you'd construct an instance of wifi.ap.AccessPoint via its for_arguments method. That in turn will take care of constructing the required instances of wifi.ap.Hostapd, wifi.ap.Dnsmasq and wifi.scheme.Scheme.

The hostapd wrapper usually uses /usr/sbin/hostapd and stores its configurations at /etc/hostapd/conf.d/. This can be overridden with the class method for_hostapd_and_confd.

The dnsmasq wrapper usually uses /usr/sbin/dnsmasq and stores its configurations at /etc/dnsmasq.conf.d/. This also can be overridden with the class method for_dnsmasq_and_confd.

The AccessPoint wrapper uses the default implementations of the hostapd and dnsmasq wrapper (so with the defaults defined above) but can be instructed to customized versions (with different binaries and/or config paths) using the class method for_classes which can be provided a custom hostapd_cls, dnsmasq_cls and/or scheme_cls with other paths defined. I tried to stick to the pattern found in the wifi.scheme.Scheme class here.

Both the hostapd and the dnsmasq wrapper support managing their wrapped processes lifecycle. So you create a new configuration (or let it be created through the AccessPoint wrapper), start the process, stop the process, list all available configurations, similar to wifi.scheme.Scheme.

The AccessPoint always manages all three of its components (hostapd, dnsmasq, scheme). So if you activate the AP, it activates all of that stuff too. It also takes care of parameterizing the scheme so it fits an access point (static ip, some iptables rules if forwarding to another interface is enabled in the post-up and pre-down sections).

Nothing of that stuff is hooked into the CLI frontend, I did not add any additional commands, since I honestly don't know how to a) make this usable due to the many configuration options necessary to get this stuff running and b) if that even would make sense (how often do you really need to quickly whip up an AP from command line).

A usage of example of all this can be found in [netconnectd]():

Btw, yes, I know, it's getting ridiculous, but that PR is still on a back burner for me due to the pending new OctoPrint release. Getting a plugin ecosystem off the ground and right on the first try eats a lot of time.

rockymeza commented 9 years ago

Oh this is great. I think I can work with this. I will try to get it running this weekend.

Good luck with Octoprint! -rocky 2015年4月22日 上午4:13于 "Gina Häußge" notifications@github.com写道:

Well, first you'd construct an instance of wifi.ap.AccessPoint via its for_arguments method https://github.com/foosel/wifi/blob/master/wifi/ap.py#L534. That in turn will take care of constructing the required instances of wifi.ap.Hostapd https://github.com/foosel/wifi/blob/master/wifi/ap.py#L43, wifi.ap.Dnsmasq https://github.com/foosel/wifi/blob/master/wifi/ap.py#L355 and wifi.scheme.Scheme.

The hostapd wrapper usually uses /usr/sbin/hostapd and stores its configurations at /etc/hostapd/conf.d/. This can be overridden with the class method for_hostapd_and_confd https://github.com/foosel/wifi/blob/master/wifi/ap.py#L37.

The dnsmasq wrapper usually uses /usr/sbin/dnsmasq and stores its configurations at /etc/dnsmasq.conf.d/. This also can be overridden with the class method for_dnsmasq_and_confd https://github.com/foosel/wifi/blob/master/wifi/ap.py#L220.

The AccessPoint wrapper uses the default implementations of the hostapd and dnsmasq wrapper (so with the defaults defined above) but can be instructed to customized versions (with different binaries and/or config paths) using the class method for_classes https://github.com/foosel/wifi/blob/master/wifi/ap.py#L503 which can be provided a custom hostapd_cls, dnsmasq_cls and/or scheme_cls with other paths defined. I tried to stick to the pattern found in the wifi.scheme.Scheme class here.

Both the hostapd and the dnsmasq wrapper support managing their wrapped processes lifecycle. So you create a new configuration (or let it be created through the AccessPoint wrapper), start the process, stop the process, list all available configurations, similar to wifi.scheme.Scheme.

The AccessPoint always manages all three of its components (hostapd, dnsmasq, scheme). So if you activate the AP, it activates all of that stuff too. It also takes care of parameterizing the scheme so it fits an access point (static ip, some iptables rules if forwarding to another interface is enabled in the post-up and pre-down sections).

Nothing of that stuff is hooked into the CLI frontend, I did not add any additional commands, since I honestly don't know how to a) make this usable due to the many configuration options necessary to get this stuff running and b) if that even would make sense (how often do you really need to quickly whip up an AP from command line).

A usage of example of all this can be found in netconnectd:

Btw, yes, I know, it's getting ridiculous, but that PR is still on a back burner for me due to the pending new OctoPrint release. Getting a plugin ecosystem off the ground and right on the first try eats a lot of time.

— Reply to this email directly or view it on GitHub https://github.com/rockymeza/wifi/pull/46#issuecomment-95116836.

mkomarinski commented 8 years ago

Any update on getting this integrated in? I'm trying to build a Raspberry Pi-based open wifi protection box (complete with VPN) and having this functionality be easily controlled from Python would make my life a bit easier.

rockymeza commented 8 years ago

I haven't had much time to work on this project. I think I will have time in June to really take a look at this pull request and merge it. I'm sorry for making everybody wait.