Back to Home

Opensource Billing ABillS - Installation on FreeBSD

ABills · mpd · billing

Opensource Billing ABillS - Installation on FreeBSD

    0. Background
    About two years ago, in front of a relatively small, but developing network, in which, by the will of fate, I turned out to be a system administrator, the task was to introduce a new billing system. The requirements turned out to be simple and quite commonplace for those places where the Internet is not a penny and far from everyone is willing to pay for unlimited:
    • Ability to create megabyte tariff plans and unlimited
    • Ability to track traffic in directions (free-city-country-world)
    • Free solution (the word opensource was still of little interest)
    • Sane web-based user and administrator interface
    • The ability to expand functionality for the future
    • Support for various payment systems (in particular, I was interested in payment by recharge cards


    Out of a large number of candidates, only two sharply remained somehow : NeTAMS and ABillS .
    After a detailed review, NeTAMS also disappeared - its working methods didn’t suit me at all, and it felt tangible that billing was just a module for it. Moreover, the web user interface to put it mildly did not work. With no alternatives, I proceeded to install ABillS.
    Perhaps I will refrain from telling all the ups and downs of studying new software, and will offer you the quintessence of my knowledge of installing the best, in my opinion, opensource billing.

    1. Installation
    In this post, I will consider the installation exclusively for FreeBSD, moreover, version 7.0 (installation on 6.x has minor, but differences). If you are a lucky owner of Linux on the server - I advise you to refer to this article by Glooom .

    1.1 Preparing the kernel
    Since billing is still a fairly serious system, I prefer to have all the functions used in the work in the kernel rather than in the modules. Therefore, we add the following options to our kernel assembly config: 1.2 ng_nat and all-all-all Unfortunately, at the moment, we cannot provide each user with a real IP. Therefore, I was faced with the task of organizing NAT. After reviewing the existing options, the choice fell on ng_nat + ng_ipfw. First, let's add
    options NETGRAPH #подключаем NETGRAPH в ядро
    options NETGRAPH_IPFW #узел ng_ipfw

    options LIBALIAS # нужен для работы ng_nat
    options NETGRAPH_NAT #узел ng_nat
    options NETGRAPH_NETFLOW #узел ng_netflow для сбора статистики
    ### Требуется для работы MPD ###
    options NETGRAPH_SPLIT
    options NETGRAPH_KSOCKET

    options NETGRAPH_SOCKET
    options NETGRAPH_BPF
    options NETGRAPH_IFACE
    options NETGRAPH_MPPC_ENCRYPTION
    options NETGRAPH_PPP
    options NETGRAPH_PPTPGRE
    options NETGRAPH_TCPMSS
    options NETGRAPH_VJC
    options NETGRAPH_TEE
    options NETGRAPH_CAR
    ### --- ###

    options IPFIREWALL #ipfw. Куда же без него
    options IPFIREWALL_VERBOSE # Поможет в отладке
    options IPFIREWALL_FORWARD # Пригодится к примеру для transparent-proxy
    options IPFIREWALL_DEFAULT_TO_ACCEPT #Дело привычки



    /etc/rc.confthe following lines: Create a file with the following contents: In this script we organize NAT users with IP 10.39.0.0/16 in IP 1.2.3.4. All this is implemented in the tables, because sometimes it becomes necessary to NAT non-contiguous ranges 1.3 Required software For normal billing, I use the following software (all of the ports):
    gateway_enable="YES" # без комментариев :)
    firewall_enable="YES" # включаем ipfw
    firewall_script="/usr/scripts/ipfw_load.sh" #файл с правилами

    /usr/script/ipfw_load.sh
    #!/bin/sh
    fwcmd="/sbin/ipfw"
    ngctl="/usr/sbin/ngctl"

    ext_if="re0" # имя внешнего интерфейса
    ext_ip="1.2.3.4" #внешний IP в который будут NAT'ится пользователи

    #Создаем узел ng_nat
    ${ngctl} mkpeer ipfw: nat 60 out
    ${ngctl} name ipfw:60 nat
    ${ngctl} connect ipfw: nat: 61 in
    ${ngctl} msg nat: setaliasaddr ${ext_ip}

    # Правила фаерволла
    ${fwcmd} -f flush #сбрасываем все правила фаерволла

    # Создаем табличку для ната (номер 127)
    ${fwcmd} table 127 flush #чистим табличку
    ${fwcmd} table 127 add 10.39.0.0/16 # добавляем сети серых ip пользователей

    #разрешаем все на loopback
    ${fwcmd} add 00001 allow ip from any to any via lo0
    # все что пришло с внешнего интерфейса заворачиваем в NAT
    ${fwcmd} add 00003 netgraph 61 all from any to ${ext_ip} in via ${ext_if}
    #Все что идет от Интернет-юзеров - в NAT
    ${fwcmd} add 60021 netgraph 60 ip from "table(127)" to any






    • apache22 (version is a matter of taste)
    • flow-tools (a set of utilities for collecting netflow streams)
    • freeradius (RADIUS server)
    • mpd5 (we will use it as a VPN server)
    • mysql-server, mysql-client (destination, I hope, no need to explain)
    • p5-DBD-mysql (to access mysql from Perl)
    • p5-Digest-MD4, p5-Digest-SHA1 (used for encryption in billing) sudo (some commands will need to be run from an unprivileged user)

      The default configuration offered in FreeBSD suits me perfectly. The only thing is to build mpd5 with ng_car from the ports, if you still decide to install on FreeBSD 6.x.

      1.4 Installing ABillS

      Despite the fact that anyone with a sound mind and sober memory for such a serious system like billing will choose a stable branch, I strongly do not recommend doing this. The fact is that in the author’s understanding stable is a “relatively stable release” and even the errors found in it are fixed in current and not stable. From personal experience I’ll say that for 1.5 years I used the current branch in work without any problems.
      Therefore, go ahead for current! I made the last line, because in the config mentions of the folder are quite common, while in BSD ABillS I set to . Now go to the folder . There we find a file that we copy into - it will become the basis for our future configuration. 2. Configuration
      # cd /usr/local/
      # cvs -d:pserver:anonymous @ abills.cvs.sourceforge.net:/cvsroot/abills login
      # cvs -z3 -d:pserver:anonymous @ abills.cvs.sourceforge.net:/cvsroot/abills checkout -r rel-0-4 abills
      # ln -s /usr/local/abills /usr/abills

      /usr/abills/usr/local/abills
      libexecconfig.pl.defaultconfig.pl



      Setting ABillS “from and to” is a complex process, inevitably associated with reading the source code. And the thing is that the documentation posted on the site is hopelessly behind the CVS version. In many ways, the author’s reluctance to update the documentation is due to the fact that installing and configuring ABillS is one of the sources of his income. Moreover, for only $ 300 a package of "full" documentation is offered. But I can’t judge him - I haven’t seen him.
      Fortunately, to solve our problems, the standard configs that come with ABillS (although the author himself does not advertise it) are quite enough. We will use his gifts. In this article, I consider a situation where all services (mysql, radius, and the netflow collector) are on the same machine, but I am sure that it will not be difficult for the reader to change settings for several systems if something happens.

      2.1. RADIUS
      So, without further ado, look at the contrib / freeradius ABillS folder and copy the files to the freeradius folder (by default it is / usr / local / etc / raddb) acct_users, clients.conf, eap.conf, rlm_perl.conf и users. We rlm_perl.confwill not forget to rename the file to radiusd.conf, and clients.confenter the IP and password to access the radius in the file ( In the example, the values ​​127.0.0.1 and radsecret will be used ).

      In order for the MPD speed limit that we are going to use to work, let's add the dictionary for MPD to the end of the dictionary: This completes the setup. We start and carefully read the output for errors. If there are no errors, we add it to the magic line and run the radius as a demon. 2.2 MPD
      VENDOR mpd 12341

      ATTRIBUTE mpd-rule 1 string mpd
      ATTRIBUTE mpd-pipe 2 string mpd
      ATTRIBUTE mpd-queue 3 string mpd
      ATTRIBUTE mpd-table 4 string mpd
      ATTRIBUTE mpd-table-static 5 string mpd
      ATTRIBUTE mpd-filter 6 string mpd
      ATTRIBUTE mpd-limit 7 string mpd
      ATTRIBUTE mpd-drop-user 154 integer mpd

      radiusd -X/etc/rc.confradiusd_enable="YES"


      Version 5 of MPD was chosen for one simple reason - it was in it that the developers finally introduced the concept of a template, eliminating the need to copy the same lines 1000 times.
      The config given by me allows connection both with mppe + mppc (hi Windows) and without it. MPD setup is complete. Do not forget to add to the line Attention! If your system is unstable and dies with a “double fault”, be sure to update the kernel source code. In the latest version, this problem has already been solved. My PR kern / 125314 about this 2.3 Configuring the Netflow Collector First of all, a few words why Netflow was chosen from all the traffic counting options:
      startup:
      #задаем пользователей админки MPD
      set user xanf somepass admin
      # По этому порту будет доступна консоль MPD
      # она нужна ABillS для завершения сессии
      set console self 127.0.0.1 5005
      set console open
      # Веб-сервер. Полезен админу поэтому открыт наружу
      set web self 0.0.0.0 5006
      set web open
      #IP адрес и порт системы, которая собирает netflow поток
      set netflow peer 127.0.0.1 9996
      set netflow self 127.0.0.1 9990
      set netflow timeouts 15 15
      set netflow hook 9000

      default:
      load pptp_server

      pptp_server:
      #чисто косметически. IP принудительно выдает RADIUS
      set ippool add pool1 10.39.0.1 10.39.255.255
      create bundle template B
      set iface idle 1800
      #"Исправляем" реализацию TCP/IP Microsoft
      set iface enable tcpmssfix
      #На интерфейсах собирается статистика трафика
      set iface enable netflow-in
      set iface enable netflow-out
      set ipcp yes vjcomp
      #VPN Server IP
      #он будет светится в подключении со стороны пользователя
      #как "удаленный сервер". Почти ни на что не влияет
      #в то же время если не хотите доставить проблем *nix-юзерам
      #сделайте его отличным от IP адреса самого VPN сервера
      set ipcp ranges 172.16.0.1/32 ippool pool1
      set ipcp dns 172.16.0.1
      set bundle enable compression
      set ccp yes mppc
      set mppc yes e40
      set mppc yes e128
      set mppc yes stateless
      set bundle yes crypt-reqd

      create link template L pptp
      set link action bundle B
      set link enable multilink
      set link yes acfcomp protocomp
      set link no pap chap
      set link enable chap
      set link yes crypt-reqd
      set link mtu 1460
      #здесь задаем локальный IP на котором MPD будет
      #ждать соединений
      set pptp self 10.37.254.253
      set link enable incoming
      #IP, пароль и порты RADIUS-сервера
      set radius server 127.0.0.1 radsecret 1812 1813
      set radius timeout 10
      set auth acct-update 300
      set auth enable radius-auth
      set auth enable radius-acct
      set radius retries 3

      /etc/rc.confmpd_enable="YES"





      • Standard solution - MPD can then be easily replaced with Mikrotik or a hardware VPN server (for example, CISCO)
      • The IPN + Netflow bundle solves two problems of the free version of ABillS - money is withdrawn from the user's account only at the end of the session and the session is broken at the border of time intervals

      First of all you need to create links in the ABillS We will give the user the right flowtools in the folder in which you will collect traffic If the folder does not exist - create it Edit the only option we are interested in - a - log rotation will be 1300 times a day, which is about one minute. 2.4 Configuring Apache Configuring the web interface is so commonplace that I only allow myself to bring a working config and say that to generate certificates you can use the script in the contrib folder of ABillS. AddHandler cgi-script .cgi Options Indexes ExecCGI FollowSymLinks AllowOverride none DirectoryIndex index.cgi Order allow, deny
      # cd /usr/abills/libexec/
      # ln -s ../Abills/modules/Ipn/trafdstats trafdstats
      # ln -s ../Abills/modules/Ipn/traffic2sql traffic2sql


      #chown flowtools /usr/local/abills/var/log/ipn/

      /usr/local/abills/var/log/ipn

      /etc/rc.conf
      flow_capture_enable="YES"
      flow_capture_datadir="/usr/local/abills/var/log/ipn/"
      flow_capture_port="9996"
      flow_capture_flags="-S 5 -n 1300 -N 0 -d 5"

      -n 1300


      sslcerts.sh

      SSLEngine on
      SSLOptions +StrictRequire
      SSLProtocol -all +TLSv1 +SSLv3
      SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM
      SSLCertificateFile /usr/local/abills/Certs/server.crt
      SSLCertificateKeyFile /usr/local/abills/Certs/server.key
      SSLVerifyClient none
      SSLProxyEngine off
      SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0

      DocumentRoot /usr/local/abills/cgi-bin
      ServerName stat.example.com
      #ServerAlias com
      ServerAdmin [email protected]
      ErrorLog /var/log/error_log
      TransferLog /var/log/access_log

      Alias / "/usr/local/abills/cgi-bin/"


      RewriteEngine on
      RewriteCond %{HTTP:Authorization} ^(.*)
      RewriteRule ^(.*) - [E=HTTP_CGI_AUTHORIZATION:%1]
      Options Indexes ExecCGI SymLinksIfOwnerMatch






      Allow from all


      Order allow, deny
      Deny from all


    #Admin interface

    AddHandler cgi-script .cgi
    Options Indexes ExecCGI FollowSymLinks
    AllowOverride none
    DirectoryIndex index.cgi
    order deny, allow
    allow from all




    If you get the 500th error - be sure to look in error.log - almost certainly there is something with the database or Perl 'u lack some kind of module.

    2.5 Configuring ABillS
    Here we come to the most delicious. Nevertheless, I allow myself not to dwell on all the features. These configs will allow you to get a workable system in the shortest time.
    We load the billing files into the created database with the name abills. The second file activates the IPN extension, which we will use. First of all, we modify config.pl
    # mysql -D abills < abills.sql
    # mysql -D abills < db/Ipn.sql




    @MODULES = ('Dv',
    'Abon',
    # 'Docs',
    'Sqlcmd',
    'Ipn',
    # 'Cards');
    );

    Ipn module is important for us to calculate traffic. The Cards module is paid ($ 60), so I left it commented out. Also pay attention to and . Here you can specify scripts that are executed when opening and closing the connection. You can not pay attention to all sorts of things - we will arrange speed cutting using another method. I personally after unsuccessful experiments generally refused to control the firewall from ABillS and therefore, in principle, I do not use the script coming from ABillS.
    $conf{default_language}='russian'; #большинство по-русски :)
    $conf{default_charset}='windows-1251';
    $conf{periodic_check}='yes';
    $conf{IPN_DEPOSIT_OPERATION}=1; #считать у нас будет именно модуль IPN
    $conf{IPN_USERMENU}=1; #включаем меню пользователя

    $conf{IPN_FW_START_RULE}$conf{IPN_FW_STOP_RULE}$conf{IPN_FW_FIRST_RULE}linkupdown

    One of the effective methods for limiting client speed when using MPD is to return the appropriate filters in the RADIUS Start-package. Thus, for example, to create a restriction on tariff plan 64, it is enough to include the following line in the RADIUS parameters of this tariff plan: In this case, the speed limit will be performed using the ng_car node, which, as my practice has shown, is much more efficient than slicing using ipfw + dummynet. Unfortunately, for some unknown reason, ABillS “out of the box” does not correctly handle the “+ =” operator in tariff plans. To correct this annoying misunderstanding, find the following lines in Auth.pm: and replace it with the following: After that, ABillS will correctly pass attributes in the "+ =" format
    mpd-limit+=out#1=all shape 64000 pass,mpd-limit+=in#1=all shape 64000 pass



    $RAD_PAIRS->{"$left"} =~ s/\"//g;
    $RAD_PAIRS->{"$left"}="\"". $RAD_PAIRS->{"$left"} .",$right\"";
    }
    else {
    $RAD_PAIRS->{"$left"}="\"$right\"";
    }



    $RAD_PAIRS->{"$left"} =~ s/\"//g;
    push( @ {$RAD_PAIRS->{"$left"} }, $right );
    }
    else {
    $RAD_PAIRS->{"$left"}= [ $right ];
    }



    Now it remains to go to the ABillS admin panel with the username and password abills and in the "System" - "NAS" section (aka "System -" Access Servers "in the Russian version) create a new NAS with the type" mpd4 "and the address" 127.0. 0.1: 5005 "

    NAS will get a number (most likely it will be" 1 "). Now open crontab and write the following line in it: do not forget to replace 1 with the number of your NAS. Now all data about the traffic of your users will be taken into account by billing. You can also add call periodic scripts in crontab: Do not make a call to Cron as recommended by the management, in our case it is not needed - and moreover , harmful - it will disconnect users at the borders of time intervals.This completes the basic configuration, and your VPM server should be ready to work.
    */5 * * * * /usr/local/abills/libexec/traffic2sql 1
    flowdir=/usr/local/abills/var/log/ipn



    1 0 * * * root /usr/abills/libexec/periodic daily
    1 0 * * * root /usr/abills/libexec/periodic monthly

    billd -all



    3. Personal impressions - a barrel of honey
    I have been using ABillS as a combat server for more than 2 years. During this time, not a single serious failure occurred, and the total downtime did not amount to probably 2 hours in total, of which an hour is a transition to new billing versions. Just once, on New Year's Eve, due to a minor error, billing began to drop all users by time-limit. It took me 15 minutes to fix this error.
    In general, the system provides very convenient reports on users, all the necessary information is stored in the database, a bunch of different modules make life easier - just a pleasant experience. Our friends bought a UTM and they had much more problems with it, even if they had paid support

    4. Personal impressions - a fly in the ointment
    However, ABillS is not perfect. I don’t use a lot of functionality (linkupdown, periodic scripts), or rather, use my own “substitutes”, since the authors do not suit me for one reason or another.
    Sometimes in current quite stupid errors happen. So after one of the updates (on average, we update billing every six months), credit users lost the ability to access the Internet due to the ">" sign put in the wrong direction when checking the credit limit of the tariff plan and user. Traffic2sql itself works in its original form rather slowly (a patch on the ABillS forum ), and when dynamically issuing IP from the pool, traffic may not be counted correctly ( bug report + patch on the ABillS forum ).
    Also, once when I switched on the Msgs module, which provided the basic “billing support” functionality from billing, two days later I was horrified to find that no tags were cut at all in the messages, which allows, for example, using IFRAME to change the tariff plan for the user as soon as the administrator look at his message.
    This is especially disappointing for the reason that 95% of the modules “appearing” for ABillS are by no means cheap commercial orders, which are then issued “for everyone”.


    DISCLAIMER instead of an afterwordEverything written above is my personal experience in using this system. My opinion is purely subjective, I do not guarantee the absolute correctness and seamlessness of the proposed solutions. Also, like any person, I could be wrong. If you have something to supplement and improve this article, I’m always happy for constructive criticism in the comments or by e-mail (in the profile)

    Read Next