6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Browser_use in the Ubuntu-Docker × Proxy × SSLインスペクション(SSL Bump)

Last updated at Posted at 2025-02-10

最近Browser Useを利用する場面があり、Proxy+SSLインスペクション環境下において、CA関連でうまく動作せず四苦八苦したので一通り準備して検証してみました。OpenAIのAPIを利用しますので、事前にAPI_KEYを取得してください。

前提

OS:Ubuntu 22.04.5 LTS
Proxy:Squid Cache: Version 4.9(on Ubuntu18.04 LTS)
Docker version: 27.3.1, build ce12230
Docker Compose version: v2.29.7
llmモデル:gpt-4o
langchain: 0.3.14
langchain-openai: 0.3.1
openai: 1.61.1
playwright: 1.50.0
browser-use: 0.1.36

0. Browser_useとは?

下記サイトが詳しく書いてあったので、参考にさせていただきました。

1. Docker関連ファイル作成/コンテナ起動

Dockerfile、RDP関連プロセスを動かす際に利用するsupervisord.conf、docker-compose.ymlを作成します。

Dockerfile
FROM ubuntu:latest

RUN apt-get update && \
    DEBIAN_FRONTED=noninteractive apt-get install -y python3-pip \
    ubuntu-desktop xrdp xfce4 xfce4-goodies dbus-x11 x11-xserver-utils \
    supervisor software-properties-common

RUN echo "xfce4-session" >~/.xsession \
    && echo "exec startxfce4" >~/.xinitrc \
    && chmod +x ~/.xinitrc

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

EXPOSE 3389

CMD ["/usr/bin/supervisord"]
supervisord.conf
[supervisord]
nodaemon=true

[program:xrdp]
command=/usr/sbin/xrdp -nodaemon

[program:xrdp-sesman]
command=/usr/sbin/xrdp-sesman -nodaemon
docker-compose.yml
services:
  rdp:
    image: ubuntu-rdp-desktop:0.1
    container_name: 'ubuntu-rdp-desktop'
    restart: always
    build:
      context: .
    tty: true
    ports:
      - "3389:3389"
    networks:
      - rdp_desktop_network

networks:
  rdp_desktop_network:
    driver: bridge

作成できたらコンテナを生成します。

docker compose up -d

以下コマンドで正しく起動しているか確認してください。

# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS                                       NAMES
xxxxxxxxxxxx   ubuntu-rdp-desktop:0.1   "/usr/bin/supervisord"   3 seconds ago   Up 3 seconds   0.0.0.0:3389->3389/tcp, :::3389->3389/tcp   ubuntu-rdp-desktop

# ss -ant|grep 3389
LISTEN 0      4096         0.0.0.0:3389      0.0.0.0:*
LISTEN 0      4096            [::]:3389         [::]:*

2. Proxy/SSLインスペクション作業

ちょうど、自宅に18.04を動かしていたjetson nanoがあったのでこれを利用しました。手順は下記サイトを参考に実施させていただきました。

myCA.pemとして作成したファイルを転送しておきましょう。

# docker cp myCA.pem ubuntu-rdp-desktop:/tmp/
Successfully copied 4.61kB to ubuntu-rdp-desktop:/tmp/

SSLインスペクションについて:参考URL

3. パスワード変更/RDPログイン

rootでログインしますので、コンテナにログインしてrootのパスワードを変更します。

# docker exec -it ubuntu-rdp-desktop /bin/bash
root@xxxxxxxxxxxx:/# passwd
New password:
BAD PASSWORD: The password fails the dictionary check - it is too simplistic/systematic
Retype new password:
passwd: password updated successfully
root@xxxxxxxxxxxx:/#

リモートデスクトップツールでログインして、usernameにroot、変更したパスワードをpassword欄に入力します。
image.png

これでデスクトップ環境が表示されました。
image.png

4. 追加パケージ、venv、証明書関連設定

まずはvenvを入れましょう。

root@xxxxxxxxxxxx:/# apt update
root@xxxxxxxxxxxx:/# apt install -y vim
root@xxxxxxxxxxxx:/# apt install -y python3-venv

ディレクトリを/rootに移動して作業し、venvで仮想環境を作成します。

root@xxxxxxxxxxxx:/# cd ~
root@xxxxxxxxxxxx:~# python3 -m venv browser_use
root@xxxxxxxxxxxx:~# source browser_use/bin/activate
(browser_use) root@xxxxxxxxxxxx:~#

続いて、証明書関連の設定を行います。事前にProxyサーバで生成したCAファイルを以下のようにコピーします。

(browser_use) root@xxxxxxxxxxxx:~# pip3 install certifi
(browser_use) root@xxxxxxxxxxxx:~# mkdir /usr/share/ca-certificates/myCA
(browser_use) root@xxxxxxxxxxxx:~# cp /tmp/myCA.pem /usr/share/ca-certificates/myCA/

ca-certificates.confに追記します。

/etc/ca-certificates.conf
mozilla/ACCVRAIZ1.crt
mozilla/AC_RAIZ_FNMT-RCM.crt
mozilla/AC_RAIZ_FNMT-RCM_SERVIDORES_SEGUROS.crt
~~~~省略~~~~
mozilla/vTrus_ECC_Root_CA.crt
mozilla/vTrus_Root_CA.crt
myCA/myCA.pem # これを追加

CAファイルの更新処理を実行します。

(browser_use) root@xxxxxxxxxxxx:~# update-ca-certificates
Updating certificates in /etc/ssl/certs...
rehash: warning: skipping ca-certificates.crt,it does not contain exactly one certificate or CRL
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
(browser_use) root@xxxxxxxxxxxx:~#

続いて、browser_useを動作させるため、必要となるpackageを入れます。

pip3 install langchain
pip3 install playwright
playwright install-deps
playwright install
pip3 install browser_use

5. 非Proxy構成でのテスト

Proxyを利用せず、直接通信させる構成でそもそもうまく動作するか確認します。OPENAIのキーを.envファイルに記載してください。

.env
OPENAI_API_KEY="sk-proj-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"  # API_KEYを記入

browser_useを動かしてみます。私のサイトでいいねの数が多いトピックを5件引っ張ってきたいと思います。

browser_test.py
import asyncio
from browser_use import Agent
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

async def main():
    agent = Agent(
        task="""
        Qiitaのnw-engineerサイトでいいねの数が多いトピックを5件表示してください。
        """,
        llm=ChatOpenAI(model="gpt-4o"),
    )
    result = await agent.run()
    print(result)

asyncio.run(main())

では、Desktop上で実行しましょう。

(browser_use) root@xxxxxxxxxxxx:~# python3 browser_test.py

実行結果

うまく抽出できていますね。ちゃんと件数まで出ています。

{
  "top_liked_topics": [
    {
      "title": "Pythonのセキュリティ関連ライブラリを試してみました。",
      "likes": 62
    },
    {
      "title": "React+FastAPI+OpenAIでヘルプレポートサイト作成",
      "likes": 39
    },
    {
      "title": "Fortigate VM(制限機能付き評価版)を利用するまでの流れ",
      "likes": 26
    },
    {
      "title": "Fortigate VMトライアルライセンス永続化",
      "likes": 22
    },
    {
      "title": "fastapi-usersでJWT認証 + MFAを使ったログイン実装",
      "likes": 21
    }
  ]
}

6. Proxy+SSLインスペクション構成

それでは、Proxy+SSLインスペクション構成でテストします。まず転送しておいたmyCA.pemファイルを/root直下にcopyします。

mv /tmp/myCA.pem ./

続いてスクリプトを追記ます。

browser_test.py
import asyncio
import certifi  ## 追加
import os       ## 追加
from browser_use import Agent
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

os.environ['REQUESTS_CA_BUNDLE'] = './myCA.pem'     ## 追加

os.environ['http_proxy'] = 'http://x.x.x.x:8080'  ## 追加
os.environ['https_proxy'] = 'http://x.x.x.x:8080' ## 追加
certifi.where = lambda: '/etc/ssl/certs/ca-certificates.crt'  ## 追加

async def main():
    agent = Agent(
        task="""
        Qiitaのnw-engineerサイトでいいねの数が多いトピックを5件表示してください。
        """,
        llm=ChatOpenAI(model="gpt-4o"),
    )
    result = await agent.run()
    print(result)

asyncio.run(main())

実行前にブラウザへCAファイルを読み込ませておきます。
Desktop上でplaywrightコマンドを実行します。

(browser_use) root@xxxxxxxxxxxx:~# playwright cr

画面右上の設定ボタンをクリックして、Settingsを選択します。
image.png

画面左側のPrivacy and Securityをクリックします。
image.png

画面中央を下にスクロールさせて、Securityを選択します。
image.png

さらに下にスクロールさせて、Manage certificates を選択します。
image.png

Manage cetificatesのポップアップ中に表示されているAuthoritiesを選択して、importボタンをクリックします。
image.png

/rootに配置したmyCA.pemを選択し、画面右下のSelectボタンをクリックします。
image.png

ポップアップのチェックボタンをすべてチェックして、OKボタンをクリックします。
image.png

新たにCA証明書(ここではorg-live-est)が表示されればOKです。
image.png

作成したスクリプト実行前に環境変数をセットして、playwrightを起動します。

(browser_use) root@xxxxxxxxxxxx:~# export https_proxy=http://x.x.x.x:8080
(browser_use) root@xxxxxxxxxxxx:~# export http_proxy=http://x.x.x.x:8080
(browser_use) root@xxxxxxxxxxxx:~# playwright cr

Google.co.jpにアクセスし、証明書を確認すると発行元(Issued By)がProxyのCAになっていることがわかります。
image.png

これでProxy+SSLインスペクション環境下におけるbrowser_useの準備ができましたので、作成したスクリプトを再び、Desktop上で再実行します。

(browser_use) root@xxxxxxxxxxxx:~# python3 browser_test.py

正しく動作しています!
image.png

NO_PROXYをos.environで定義すればローカルアドレスも操作できるのでかなり使い勝手がよさそうです。

その他

ollamaを利用してローカルLLMも使えるようなのですが、できれば自前のAPIで利用したいとおもっているのでもう少しコードを解析したいと思います。

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?