Thursday, May 12, 2011

How to share 3G internet in a local area network

Let's аssume that you have a computer connected to the Internet via 3G modem, and you want to share it to another computer connected in a Ethernet local network.

The scheme of the connection will be like this:
Internet ---> | PC1 (the gateway) | ---> PC2 (switch) .. etc

Initial conditions:

Both computers are connected over a network.
We have 3G modem and Ethernet network card in PC1 :
ppp0 - connected to Internet
eth0 - connected to LAN

and eth0 in PC2

Customize PC1

Set up the Ethernet card (eth0) as follows:
IP: 192.168.0.1
Netmask: 255.255.255.0
or type in the console:
ifconfig eth0 192.168.0.1 netmask 255.255.255.0
ifconfig eth1 up

Allow the packets

To do this, edit /etc/sysctl.conf: insert a line
net.ipv4.ip_forward = 1

Run the following line in the terminal:
sudo sysctl-w net.ipv4.ip_forward = "1"
in order to apply this rule before reboot.

Install iptables.
sudo apt-get install iptables
Type the following rule (for the transfer of Internet second computer) and save it.
iptables-t nat-A POSTROUTING-o ppp0-j MASQUERADE

Install dnsmasq
sudo apt-get install dnsmasq
Run it:
sudo service dnsmasq start

Customize PC2

IP: 192.168.0.2
Netmask / Mask: 255.255.255.0
Gateway / Gateway: 192.168.0.1
DNS: 192.168.0.1

Now the second computer should now be connected to the Internet.
If after restarting iptables rules are not restored, add
iptables-t nat-A POSTROUTING-o ppp0 -j MASQUERADE
in any startup script (rc.local for example)

Sunday, December 12, 2010

Network-manager auto-reconnect [SOLVED]

Many times I had the following message from my network manager in Ubuntu: GSM network Disconnected — you are now offline. It was not possible to reconnect again with Network-manager, for sure I checked "connect automaticly" in its option, but that didn't help. The only solution was to unplug my USB modem and plug it in again to my pc. It was very annoying.

I have found many errors related to this problem in logs.

First, nm-applet gives

** (nm-applet:32060): WARNING **: Error in getting active connection 'Vpn' property: (19) Method "Get" with signature "ss" on interface "org.freedesktop.DBus.Properties" doesn't exist
** (nm-applet:32060): WARNING **: _nm_object_array_demarshal: couldn't create object for /org/freedesktop/NetworkManager/ActiveConnection/56


Second, dmesg gives

[253846.006408] option: option_instat_callback: error -108
[253846.006795] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[253846.010641] option 2-3:1.0: device disconnected


There are errors from /var/log/messages

Dec 10 03:32:49 ubuntu-main pppd[5158]: LCP terminated by peer
Dec 10 03:32:49 ubuntu-main pppd[5158]: Connect time 26.2 minutes.
Dec 10 03:32:49 ubuntu-main pppd[5158]: Sent 857127 bytes, received 3813495 bytes.
Dec 10 03:32:49 ubuntu-main pppd[5158]: Modem hangup
Dec 10 03:32:49 ubuntu-main pppd[5158]: Connection terminated.


It seems that my Internet service provider (ISP) terminates the connection and network-manager is not capable to make auto-reconnection.

Here is a solution I have found.

Try the to run the following two lines it the terminal:


sudo killall modem-manager nm-applet
modem-manager & nm-applet


If you can reconnect after that - this solution is for you.
In fact, this is just a restart for modem-manager and nm-applet.

This could be the end but I decided to write a script to make it automatically cause due to my ISP I could be disconnected many time per day.

I wrote the script in python that check Internet connection every minute and run the above mentioned commands to make reconnection if its necessary. Here is the script.

#!/usr/bin/env python

"""
auto-reconnect.py - a code to accomplish auto reconnection to the internet
source: http://best-ubuntu-notebook.blogspot.com/
python version '2.6.5'

"""

import urllib2,os,time

#loading from a file
def download_lines(name):
  inputfile = open(name, 'r') # open file for reading
  lines = inputfile.readlines()
  inputfile.close()
  return lines[0].replace('\n','')

#checking function
def check_connection (site):

  print 'Checking connection...'

  req = urllib2.Request(site)

  flag=False

  try:
    u = urllib2.urlopen(req)
  except urllib2.URLError, e:
    print 'URLError'
  except urllib2.HTTPError, e:
    print 'HTTPError'
  except Exception, e:
    print 'Exception'
  else:
    print
    print 'We are connected!'
    flag=True
    
  return flag

delay=60 #delay in seconds to give nm-applet the possibility to make a connection
big_delay=60 #time between Internet connection checking

directive_path='...'
path_to_kill_modem_manager_script='...'

test_site='http://www.microsoft.com/'

directive=download_lines(directive_path)

if directive=='continue':
  flag_continue=True
else:
  flag_continue=False

while flag_continue:

  trial=0

  flag=check_connection(test_site)

  while not flag:

    trial=trial+1

    print
    print 'Trial number: ', trial

    os.system('sudo '+path_to_kill_modem_manager_script)

    os.system('killall nm-applet')
    os.system('modem-manager')

    os.system('nohup nm-applet &')

    if not flag:
      print 'Wait ',delay,'sec before cheking'
      time.sleep(delay)

    flag=check_connection(test_site)

    directive=download_lines(directive_path)
    
    if directive=='continue':
      flag_continue=True
    else:
      print 'Exit'
      flag_continue=False
      flag=True

  if flag_continue:
    print 'It seems that we are online, waiting ',big_delay,'sec before the next checking of the Internet connection'
    time.sleep(big_delay)


Additionally you have to specify the path to two files in variables directive_path and path_to_kill_modem_manager_script. First file (name it as directive) has to have a word continue if you want this script to run continuously. The second (name it as kill_modem_manager_script, respectively) has to have the following content:

#!/bin/bash
killall modem-manager


It is clear that the last is a bash script to 'kill' modem-manager. You have to give to yourself a permission to run this script as the root without entering a password. For this you have to run in the terminal
sudo visudo

and add the following line:
username ALL=NOPASSWD:

Here you have to substitute your username there and also to add the same path as in the variable path_to_kill_modem_manager_script after ALL=NOPASSWD:. And of course you have to add execute permission to kill_modem_manager_script.

P.S. I am sure that there are some much simpler solutions, but the proposed script is working and and working very well. Anyway, you are welcome to comment it.