Реалиазация шлюза на Cisco

Материал из BiTel WiKi

(Различия между версиями)
Перейти к: навигация, поиск
(Новая: этот тип шлюза смотрит к какому источнику привязан ип адрес клиента после чего идет на этот роутер и д...)
Строка 58: Строка 58:
public class RouterGateWorker extends GateWorker {
public class RouterGateWorker extends GateWorker {
-
private static SetupData setup = new SetupData("data.data");
+
  private static SetupData setup = new SetupData("data.data");
-
static final long maxSize = 64;
+
  static final long maxSize = 64;
-
@Override
+
  @Override
-
protected void doSync() {
+
  protected void doSync() {
-
Long exclude[];
+
    Long exclude[];
-
DefaultServerSetup gateSetup = new DefaultServerSetup(gate.getConfig(), "\r\n");
+
    DefaultServerSetup gateSetup = new DefaultServerSetup(gate.getConfig(), "\r\n");
-
HashMap<String, ArrayList<String>> cmds = new HashMap<String, ArrayList<String>>();
+
    HashMap<String, ArrayList<String>> cmds = new HashMap<String, ArrayList<String>>();
-
String login = gateSetup.getStringValue("login", "root");
+
    String login = gateSetup.getStringValue("login", "root");
-
String pswd = gateSetup.getStringValue("password", "passwd");
+
    String pswd = gateSetup.getStringValue("password", "passwd");
-
int debug = gateSetup.getIntValue("debug", gate.getGateType().getConfigSetup().getIntValue("debug", 0));
+
    int debug = gateSetup.getIntValue("debug", gate.getGateType().getConfigSetup().getIntValue("debug", 0));
-
int mid = gateSetup.getIntValue("mid", gate.getGateType().getConfigSetup().getIntValue("mid", -1));
+
    int mid = gateSetup.getIntValue("mid", gate.getGateType().getConfigSetup().getIntValue("mid", -1));
-
ArrayList<Long> ex = new ArrayList<Long>();
+
    ArrayList<Long> ex = new ArrayList<Long>();
-
for (Iterator it = gateSetup.getOrderedValues("exclude.").iterator(); it.hasNext();) {
+
    for (Iterator it = gateSetup.getOrderedValues("exclude.").iterator(); it.hasNext();) {
-
String s = (String) it.next();
+
      String s = (String) it.next();
-
s = s.trim();
+
      s = s.trim();
-
StringTokenizer st = new StringTokenizer(s, "/");
+
      StringTokenizer st = new StringTokenizer(s, "/");
-
if (st.countTokens() != 2) {
+
      if (st.countTokens() != 2) {
-
log.error("Cant parse gate config: " + s);
+
        log.error("Cant parse gate config: " + s);
-
gateErrors.append("Ошибка конфига\n");
+
        gateErrors.append("Ошибка конфига\n");
-
continue;
+
        continue;
-
}
+
      }
-
ex.add(aton(st.nextToken()));
+
      ex.add(aton(st.nextToken()));
-
ex.add(aton(st.nextToken()));
+
      ex.add(aton(st.nextToken()));
-
}
+
    }
-
exclude = ex.toArray(new Long[ex.size()]);
+
    exclude = ex.toArray(new Long[ex.size()]);
-
Connection con = null;
+
    Connection con = null;
-
PreparedStatement ps = null;
+
    PreparedStatement ps = null;
-
try {
+
    try {
-
con = setup.getDBConnection();
+
      con = setup.getDBConnection();
-
for (Iterator<UserStatus> it = statusList.iterator(); it.hasNext();) {
+
      for (Iterator<UserStatus> it = statusList.iterator(); it.hasNext();) {
-
UserStatus us = it.next();
+
        UserStatus us = it.next();
-
int cid = us.contractId;
+
        int cid = us.contractId;
-
log.debug("CID:" + cid + " status:" + us.status);
+
        log.debug("CID:" + cid + " status:" + us.status);
-
ps = con.prepareStatement("select * from ipn_user_range_" + mid + " where cid=? and "
+
        ps = con.prepareStatement("select * from ipn_user_range_" + mid + " where cid=? and "
-
+ " ( date1 is null or date1<=now() ) and ( date2 is null or date2>=now() )");
+
            + " ( date1 is null or date1<=now() ) and ( date2 is null or date2>=now() )");
-
ps.setInt(1, cid);
+
        ps.setInt(1, cid);
-
ResultSet rs = ps.executeQuery();
+
        ResultSet rs = ps.executeQuery();
-
while (rs.next()) {
+
        while (rs.next()) {
-
int aid = rs.getInt("id");
+
          int aid = rs.getInt("id");
-
long a1 = rs.getBigDecimal("addr1").longValue();
+
          long a1 = rs.getBigDecimal("addr1").longValue();
-
long a2 = rs.getBigDecimal("addr2").longValue();
+
          long a2 = rs.getBigDecimal("addr2").longValue();
-
assert a1 < a2;
+
          assert a1 < a2;
-
PreparedStatement psSrc = con
+
          PreparedStatement psSrc = con
-
.prepareStatement("select s.title,s.host_or_dir,i.number,i.title from ipn_user_source_"
+
              .prepareStatement("select s.title,s.host_or_dir,i.number,i.title from ipn_user_source_"
-
+ mid + " us join source s on us.source_id=s.id left outer join ipn_iface_" + mid
+
                  + mid + " us join source s on us.source_id=s.id left outer join ipn_iface_" + mid
-
+ " i on us.source_id=i.source_id and us.iface=i.number where aid=?");
+
                  + " i on us.source_id=i.source_id and us.iface=i.number where aid=?");
-
psSrc.setInt(1, aid);
+
          psSrc.setInt(1, aid);
-
ResultSet rs2 = psSrc.executeQuery();
+
          ResultSet rs2 = psSrc.executeQuery();
-
while (rs2.next()) {
+
          while (rs2.next()) {
-
int n = rs2.getInt(3);
+
            int n = rs2.getInt(3);
-
String rtr = rs2.getString(2);
+
            String rtr = rs2.getString(2);
-
if (n < 0 && a1!=0 ) {
+
            if (n < 0 && a1!=0 ) {
-
// ANY и addr1==0.0.0.0  
+
              // ANY и addr1==0.0.0.0  
-
addcmd: {
+
              addcmd: {
-
// проверяем размер
+
                // проверяем размер
-
if (Math.abs(a2 - a1) > maxSize) {
+
                if (Math.abs(a2 - a1) > maxSize) {
-
log.error("Exceed max network size, " + ntoa(a1) + "-" + ntoa(a2) + " cid:" + cid);
+
                  log.error("Exceed max network size, " + ntoa(a1) + "-" + ntoa(a2) + " cid:" + cid);
-
gateErrors.append("Превышен максимальный размер сети " + ntoa(a1) + "-" + ntoa(a2) + "\n");
+
                  gateErrors.append("Превышен максимальный размер сети " + ntoa(a1) + "-" + ntoa(a2) + "\n");
-
break addcmd;
+
                  break addcmd;
-
}
+
                }
-
// проверяем попадают ли адреса в защищенный
+
                // проверяем попадают ли адреса в защищенный
-
// диапазон
+
                // диапазон
-
for (int i = 0; i < exclude.length; i += 2)
+
                for (int i = 0; i < exclude.length; i += 2)
-
if ((exclude[i] == (a1 & exclude[i + 1])) || (exclude[i] == (a2 & exclude[i + 1]))) {
+
                  if ((exclude[i] == (a1 & exclude[i + 1])) || (exclude[i] == (a2 & exclude[i + 1]))) {
-
log.error("Network excluded, " + ntoa(a1) + "-" + ntoa(a2) + " cid:" + cid);
+
                    log.error("Network excluded, " + ntoa(a1) + "-" + ntoa(a2) + " cid:" + cid);
-
gateErrors.append("Сеть защищена конфигом " + ntoa(a1) + "-" + ntoa(a2) + "\n");
+
                    gateErrors.append("Сеть защищена конфигом " + ntoa(a1) + "-" + ntoa(a2) + "\n");
-
break addcmd;
+
                    break addcmd;
-
}
+
                  }
-
// все хорошо
+
                // все хорошо
-
for (long i = a1; i <= a2; i++)
+
                for (long i = a1; i <= a2; i++)
-
addToCmdList(cmds, rtr, (us.status == 0 ? "no " : "") + "ip route " + ntoa(i)
+
                  addToCmdList(cmds, rtr, (us.status == 0 ? "no " : "") + "ip route " + ntoa(i)
-
+ " 255.255.255.255 null0 tag 1901");
+
                      + " 255.255.255.255 null0 tag 1901");
-
}
+
              }
-
} else {
+
            } else {
-
// определенный интерфейс и addr1 == 0.0.0.0 (точно VPN)
+
              // определенный интерфейс и addr1 == 0.0.0.0 (точно VPN)
-
addToCmdList(cmds, rtr, "interface " + rs2.getString(4));
+
              addToCmdList(cmds, rtr, "interface " + rs2.getString(4));
-
addToCmdList(cmds, rtr, (us.status == 0 ? "no " : "") + "shutdown");
+
              addToCmdList(cmds, rtr, (us.status == 0 ? "no " : "") + "shutdown");
-
}
+
            }
-
}
+
          }
-
}
+
        }
-
}
+
      }
-
} catch (SQLException e) {
+
    } catch (SQLException e) {
-
log.error(e.getLocalizedMessage(), e);
+
      log.error(e.getLocalizedMessage(), e);
-
gateErrors.append("Ошибка запроса в БД " + e.getLocalizedMessage() + "\n");
+
      gateErrors.append("Ошибка запроса в БД " + e.getLocalizedMessage() + "\n");
-
} finally {
+
    } finally {
-
if (ps != null)
+
      if (ps != null)
-
try {
+
        try {
-
ps.close();
+
          ps.close();
-
} catch (SQLException e) {
+
        } catch (SQLException e) {
-
log.error(e.getLocalizedMessage(), e);
+
          log.error(e.getLocalizedMessage(), e);
-
gateErrors.append("Ошибка запроса в БД " + e.getLocalizedMessage() + "\n");
+
          gateErrors.append("Ошибка запроса в БД " + e.getLocalizedMessage() + "\n");
-
}
+
        }
-
}
+
    }
-
if (debug > 0) {
+
    if (debug > 0) {
-
for (String host : cmds.keySet()) {
+
      for (String host : cmds.keySet()) {
-
log.debug("Debug mode telnet " + login + "@" + host);
+
        log.debug("Debug mode telnet " + login + "@" + host);
-
for (String c : cmds.get(host))
+
        for (String c : cmds.get(host))
-
log.debug(host+"  "+c);
+
          log.debug(host+"  "+c);
-
//gateErrors.append("режим отладки\n");
+
        //gateErrors.append("режим отладки\n");
-
}
+
      }
-
} else
+
    } else
-
for (String host : cmds.keySet()) {
+
      for (String host : cmds.keySet()) {
-
try {
+
        try {
-
log.debug("telnet " + login + "@" + host);
+
          log.debug("telnet " + login + "@" + host);
-
Expect4j exp = ExpectUtils.telnet(host, 23);
+
          Expect4j exp = ExpectUtils.telnet(host, 23);
-
if (exp.expect("ogin:") < 0)
+
          if (exp.expect("ogin:") < 0)
-
throw new RuntimeException("failed match login prompt");
+
            throw new RuntimeException("failed match login prompt");
-
exp.send(login + "\n");
+
          exp.send(login + "\n");
-
if (exp.expect("assword:") < 0)
+
          if (exp.expect("assword:") < 0)
-
throw new RuntimeException("failed match password prompt");
+
            throw new RuntimeException("failed match password prompt");
-
exp.send(pswd + "\n");
+
          exp.send(pswd + "\n");
-
if (exp.expect("#") < 0)
+
          if (exp.expect("#") < 0)
-
throw new RuntimeException("failed match prompt 0");
+
            throw new RuntimeException("failed match prompt 0");
-
exp.send("conf term\n");
+
          exp.send("conf term\n");
-
for (String c : cmds.get(host)) {
+
          for (String c : cmds.get(host)) {
-
log.debug(c);
+
            log.debug(c);
-
if (exp.expect("#") < 0)
+
            if (exp.expect("#") < 0)
-
throw new RuntimeException("failed match prompt 1");
+
              throw new RuntimeException("failed match prompt 1");
-
exp.send(c + "\n");
+
            exp.send(c + "\n");
-
}
+
          }
-
if (exp.expect("#") < 0)
+
          if (exp.expect("#") < 0)
-
throw new RuntimeException("failed match prompt 2");
+
            throw new RuntimeException("failed match prompt 2");
-
exp.send("end\n");
+
          exp.send("end\n");
-
if (exp.expect("#") < 0)
+
          if (exp.expect("#") < 0)
-
throw new RuntimeException("failed match prompt 3");
+
            throw new RuntimeException("failed match prompt 3");
-
exp.send("exit\n");
+
          exp.send("exit\n");
-
exp.close();
+
          exp.close();
-
} catch (Exception e) {
+
        } catch (Exception e) {
-
log.error("telnet " + login + "@" + host);
+
          log.error("telnet " + login + "@" + host);
-
for (String c : cmds.get(host))
+
          for (String c : cmds.get(host))
-
log.error(c);
+
            log.error(c);
-
log.error(e.getLocalizedMessage(), e);
+
          log.error(e.getLocalizedMessage(), e);
-
gateErrors.append("Ошибка " + e.getLocalizedMessage() + "\n");
+
          gateErrors.append("Ошибка " + e.getLocalizedMessage() + "\n");
-
}
+
        }
-
}
+
      }
-
}
+
  }
-
public final static String ntoa(long n) {
+
  public final static String ntoa(long n) {
-
return (n >> 24 & 0xff) + "." + (n >> 16 & 0xff) + "." + (n >> 8 & 0xff) + "." + (n & 0xff);
+
    return (n >> 24 & 0xff) + "." + (n >> 16 & 0xff) + "." + (n >> 8 & 0xff) + "." + (n & 0xff);
-
}
+
  }
-
public final static long aton(String a) {
+
  public final static long aton(String a) {
-
long n = 0;
+
    long n = 0;
-
StringTokenizer st = new StringTokenizer(a, ".");
+
    StringTokenizer st = new StringTokenizer(a, ".");
-
try {
+
    try {
-
while (st.hasMoreTokens()) {
+
      while (st.hasMoreTokens()) {
-
n |= n << 8 | (Integer.parseInt(st.nextToken()) & 0xff);
+
        n |= n << 8 | (Integer.parseInt(st.nextToken()) & 0xff);
-
}
+
      }
-
} catch (NumberFormatException e) {
+
    } catch (NumberFormatException e) {
-
return 0;
+
      return 0;
-
}
+
    }
-
return n;
+
    return n;
-
}
+
  }
-
private final void addToCmdList(HashMap<String, ArrayList<String>> cmds, String rtr, String c) {
+
  private final void addToCmdList(HashMap<String, ArrayList<String>> cmds, String rtr, String c) {
-
ArrayList<String> l = cmds.get(rtr);
+
    ArrayList<String> l = cmds.get(rtr);
-
if (l == null) {
+
    if (l == null) {
-
l = new ArrayList<String>();
+
      l = new ArrayList<String>();
-
cmds.put(rtr, l);
+
      cmds.put(rtr, l);
-
}
+
    }
-
l.add(c);
+
    l.add(c);
-
}
+
  }
}
}
</source >
</source >
-
12:05, 8 июня 2008 (UTC)~
+
--[[Участник:Blib|Blib]] 12:08, 8 июня 2008 (UTC)

Версия 12:08, 8 июня 2008

этот тип шлюза смотрит к какому источнику привязан ип адрес клиента после чего идет на этот роутер и делает

ip route адрес клиента Null0

т.е. все пакеты клиента отправляются в /dev/null (если разрешен RPF то и входящие пакеты отправляются в null)

если адреса привязаны к индивидуальному интерфейсу то скрипт делает shutdown этого интерфейса


Настройка типа шлюза в бгбиллинге. Клиент БГБиллинга -> Модули -> IPN модуль -> Типы шлюзов Добавляем новый шлюз. Название: xxx Комментарий: Универсальный шлюз Cisco Конфигурация:

gate_manager.class=ru.dsi.bg.server.RouterGateWorker


настройка индивидуального шлюза

login=xxx
password=xxx
exclude.1=10.10.0.0/255.255.255.0
debug=1

login/password - логин на роутеры

exclude - исключает на всякий случай наши адреса что бы случайно не отключить самого себя

debug - 1- значит что ничего не делать а только писать в лог что бы было бы сделано

после этого

нужно скомпилировать класс сделать jar и положить в директорию lib на сервере

package ru.dsi.bg.server;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
 
import bitel.billing.server.ipn.GateWorker;
import bitel.billing.server.ipn.UserStatus;
import bitel.billing.server.util.DefaultServerSetup;
import bitel.billing.server.util.SetupData;
import expect4j.Expect4j;
import expect4j.ExpectUtils;
 
public class RouterGateWorker extends GateWorker {
 
  private static SetupData setup = new SetupData("data.data");
 
  static final long maxSize = 64;
 
  @Override
  protected void doSync() {
    Long exclude[];
    DefaultServerSetup gateSetup = new DefaultServerSetup(gate.getConfig(), "\r\n");
    HashMap<String, ArrayList<String>> cmds = new HashMap<String, ArrayList<String>>();
    String login = gateSetup.getStringValue("login", "root");
    String pswd = gateSetup.getStringValue("password", "passwd");
    int debug = gateSetup.getIntValue("debug", gate.getGateType().getConfigSetup().getIntValue("debug", 0));
    int mid = gateSetup.getIntValue("mid", gate.getGateType().getConfigSetup().getIntValue("mid", -1));
    ArrayList<Long> ex = new ArrayList<Long>();
    for (Iterator it = gateSetup.getOrderedValues("exclude.").iterator(); it.hasNext();) {
      String s = (String) it.next();
      s = s.trim();
      StringTokenizer st = new StringTokenizer(s, "/");
      if (st.countTokens() != 2) {
        log.error("Cant parse gate config: " + s);
        gateErrors.append("Ошибка конфига\n");
        continue;
      }
      ex.add(aton(st.nextToken()));
      ex.add(aton(st.nextToken()));
    }
    exclude = ex.toArray(new Long[ex.size()]);
 
    Connection con = null;
    PreparedStatement ps = null;
    try {
      con = setup.getDBConnection();
      for (Iterator<UserStatus> it = statusList.iterator(); it.hasNext();) {
        UserStatus us = it.next();
        int cid = us.contractId;
 
        log.debug("CID:" + cid + " status:" + us.status);
        ps = con.prepareStatement("select * from ipn_user_range_" + mid + " where cid=? and "
            + " ( date1 is null or date1<=now() ) and ( date2 is null or date2>=now() )");
 
        ps.setInt(1, cid);
 
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
          int aid = rs.getInt("id");
          long a1 = rs.getBigDecimal("addr1").longValue();
          long a2 = rs.getBigDecimal("addr2").longValue();
          assert a1 < a2;
          PreparedStatement psSrc = con
              .prepareStatement("select s.title,s.host_or_dir,i.number,i.title from ipn_user_source_"
                  + mid + " us join source s on us.source_id=s.id left outer join ipn_iface_" + mid
                  + " i on us.source_id=i.source_id and us.iface=i.number where aid=?");
          psSrc.setInt(1, aid);
          ResultSet rs2 = psSrc.executeQuery();
          while (rs2.next()) {
            int n = rs2.getInt(3);
            String rtr = rs2.getString(2);
            if (n < 0 && a1!=0 ) {
              // ANY и addr1==0.0.0.0 
              addcmd: {
                // проверяем размер
                if (Math.abs(a2 - a1) > maxSize) {
                  log.error("Exceed max network size, " + ntoa(a1) + "-" + ntoa(a2) + " cid:" + cid);
                  gateErrors.append("Превышен максимальный размер сети " + ntoa(a1) + "-" + ntoa(a2) + "\n");
                  break addcmd;
                }
                // проверяем попадают ли адреса в защищенный
                // диапазон
                for (int i = 0; i < exclude.length; i += 2)
                  if ((exclude[i] == (a1 & exclude[i + 1])) || (exclude[i] == (a2 & exclude[i + 1]))) {
                    log.error("Network excluded, " + ntoa(a1) + "-" + ntoa(a2) + " cid:" + cid);
                    gateErrors.append("Сеть защищена конфигом " + ntoa(a1) + "-" + ntoa(a2) + "\n");
                    break addcmd;
                  }
                // все хорошо
                for (long i = a1; i <= a2; i++)
                  addToCmdList(cmds, rtr, (us.status == 0 ? "no " : "") + "ip route " + ntoa(i)
                      + " 255.255.255.255 null0 tag 1901");
              }
            } else {
              // определенный интерфейс и addr1 == 0.0.0.0 (точно VPN)
              addToCmdList(cmds, rtr, "interface " + rs2.getString(4));
              addToCmdList(cmds, rtr, (us.status == 0 ? "no " : "") + "shutdown");
            }
          }
        }
      }
    } catch (SQLException e) {
      log.error(e.getLocalizedMessage(), e);
      gateErrors.append("Ошибка запроса в БД " + e.getLocalizedMessage() + "\n");
    } finally {
      if (ps != null)
        try {
          ps.close();
        } catch (SQLException e) {
          log.error(e.getLocalizedMessage(), e);
          gateErrors.append("Ошибка запроса в БД " + e.getLocalizedMessage() + "\n");
        }
    }
    if (debug > 0) {
      for (String host : cmds.keySet()) {
        log.debug("Debug mode telnet " + login + "@" + host);
        for (String c : cmds.get(host))
          log.debug(host+"  "+c);
        //gateErrors.append("режим отладки\n");
      }
    } else
      for (String host : cmds.keySet()) {
        try {
          log.debug("telnet " + login + "@" + host);
          Expect4j exp = ExpectUtils.telnet(host, 23);
          if (exp.expect("ogin:") < 0)
            throw new RuntimeException("failed match login prompt");
          exp.send(login + "\n");
          if (exp.expect("assword:") < 0)
            throw new RuntimeException("failed match password prompt");
          exp.send(pswd + "\n");
          if (exp.expect("#") < 0)
            throw new RuntimeException("failed match prompt 0");
          exp.send("conf term\n");
 
          for (String c : cmds.get(host)) {
            log.debug(c);
            if (exp.expect("#") < 0)
              throw new RuntimeException("failed match prompt 1");
            exp.send(c + "\n");
          }
          if (exp.expect("#") < 0)
            throw new RuntimeException("failed match prompt 2");
          exp.send("end\n");
          if (exp.expect("#") < 0)
            throw new RuntimeException("failed match prompt 3");
          exp.send("exit\n");
          exp.close();
        } catch (Exception e) {
          log.error("telnet " + login + "@" + host);
          for (String c : cmds.get(host))
            log.error(c);
          log.error(e.getLocalizedMessage(), e);
          gateErrors.append("Ошибка " + e.getLocalizedMessage() + "\n");
        }
      }
  }
 
  public final static String ntoa(long n) {
    return (n >> 24 & 0xff) + "." + (n >> 16 & 0xff) + "." + (n >> 8 & 0xff) + "." + (n & 0xff);
  }
 
  public final static long aton(String a) {
    long n = 0;
    StringTokenizer st = new StringTokenizer(a, ".");
    try {
      while (st.hasMoreTokens()) {
        n |= n << 8 | (Integer.parseInt(st.nextToken()) & 0xff);
      }
    } catch (NumberFormatException e) {
      return 0;
    }
    return n;
  }
 
  private final void addToCmdList(HashMap<String, ArrayList<String>> cmds, String rtr, String c) {
    ArrayList<String> l = cmds.get(rtr);
    if (l == null) {
      l = new ArrayList<String>();
      cmds.put(rtr, l);
    }
    l.add(c);
  }
}

--Blib 12:08, 8 июня 2008 (UTC)

Личные инструменты